De ternaire voorwaardelijke operator (?:) maakt het mogelijk om een van de twee expressies te berekenen en retourneren op basis van een voorwaarde:
result = cond ? expr_true : expr_false;
int a = 10, b = 0; int max = (a > b) ? a : b; // max = 10
"Als twee expressies van de ternaire operator objecten van verschillende types retourneren (bijvoorbeeld een pointer en nul), wat is dan het type van het resultaat?"
Velen beweren dat de compiler altijd het type resultaat "raad". In werkelijkheid, als een van de expressies een pointer is en de andere 0 of NULL, dan heeft het resultaat het type van de pointer. Als het verschil complexer is — bijvoorbeeld, een pointer van een ander type of een int en een enum type — kan er onopgemerkt dataverlies optreden, en soms geeft de compiler een foutmelding.
struct node *p = NULL; void *v = cond ? p : NULL; // ok void *z = cond ? p : 0; // ok int i = cond ? 0 : "abc"; // fout: incompatibele types
Verhaal
In een groot project met cross-compilatie produceerde de gebruikte expressie
cond ? ptr : 0een pointer met de ene compiler en een int met de andere (waarbij 0 strikt als int werd geïnterpreteerd). Het systeem faalde bij de poging om het resultaat als pointer te gebruiken.
Verhaal
In een financieel pakket, waar de retourfuncties de ternaire operator met "blote" literalen gebruikten (
cond ? 0.0 : 1), werd het resultaattype per ongeluk double, terwijl int werd verwacht, wat leidde tot vergelijkings- en afdrukfouten.
Verhaal
In een van de bibliotheken werd een aanroep gedaan met een expressie met een neveneffect:
flag ? inc(x) : dec(x). Bij het refactoren ontdekte men een verborgen fout: beide expressies riepen de functie aan (met hun eigen side-effects), terwijl men verwachtte dat er maar één zou worden uitgevoerd. De verwarring met geneste macro's leidde tot dubbele wijziging van de waarde, wat pas tijdens gedetailleerd testen werd ontdekt.