Der ternäre Bedingungsoperator (?:) ermöglicht die Auswertung und Rückgabe eines von zwei Ausdrücken, abhängig von einer Bedingung:
result = cond ? expr_true : expr_false;
int a = 10, b = 0; int max = (a > b) ? a : b; // max = 10
"Wenn zwei Ausdrücke des ternären Operators Objekte unterschiedlichen Typs zurückgeben (z. B. einen Zeiger und null), was wird der Typ des Ergebnisses sein?"
Viele behaupten, dass der Compiler immer den Typ des Ergebnisses "errät". Tatsächlich, wenn einer der Ausdrücke ein Zeiger ist und der andere 0 oder NULL, dann wird das Ergebnis den Typ des Zeigers haben. Wenn der Unterschied komplizierter ist – z. B. wird ein Zeiger eines anderen Typs oder der Typ int und der Typ enum zurückgegeben – kann es zu einer nicht offensichtlichen Informationsverluste kommen, oder der Compiler gibt einen Fehler aus.
struct node *p = NULL; void *v = cond ? p : NULL; // ok void *z = cond ? p : 0; // ok int i = cond ? 0 : "abc"; // Fehler: inkompatible Typen
Geschichte
In einem großen Projekt mit Cross-Compilation gab der Ausdruck
cond ? ptr : 0einen Zeiger bei einem Compiler und int bei einem anderen zurück (wo 0 strikt als int interpretiert wurde). Das System stürzte ab, als versucht wurde, das Ergebnis als Zeiger zu verwenden.
Geschichte
In einem Finanzpaket, wo Rückgabefunktionen den ternären Operator mit "rohen" Literalen (
cond ? 0.0 : 1) verwendeten, wurde der Typ des Ergebnisses aus Unachtsamkeit zu double, obwohl int erwartet wurde, was zu Vergleichs- und Druckfehlern führte.
Geschichte
In einer der Bibliotheken wurde ein Aufruf mit einem Ausdruck mit Nebeneffekten gemacht:
flag ? inc(x) : dec(x). Bei der Umgestaltung wurde ein versteckter Fehler entdeckt: beide Ausdrücke riefen die Funktion auf (mit ihren Nebeneffekten), obwohl erwartet wurde, dass nur einer ausgeführt wird. Verwirrung durch verschachtelte Makros führte zu einer doppelten Veränderung des Wertes, was erst während ausführlicher Testungen entdeckt wurde.