L'operatore condizionale ternario (?:) consente di calcolare e restituire una delle due espressioni a seconda della condizione:
result = cond ? expr_true : expr_false;
int a = 10, b = 0; int max = (a > b) ? a : b; // max = 10
"Se due espressioni dell'operatore ternario restituiscono oggetti di tipo diverso (ad esempio, un puntatore e zero), qual è il tipo del risultato?"
Molti sostengono che il compilatore "indovina" sempre il tipo del risultato. In realtà, se una delle espressioni è un puntatore e l'altra è 0 o NULL, il risultato avrà il tipo del puntatore. Se invece la differenza è più complessa - ad esempio, un puntatore di tipo diverso o un tipo int e un tipo enum - è possibile una perdita di informazioni non immediata, e talvolta il compilatore restituisce un errore.
struct node *p = NULL; void *v = cond ? p : NULL; // ok void *z = cond ? p : 0; // ok int i = cond ? 0 : "abc"; // errore: tipi incompatibili
Storia
In un grande progetto con cross-compilazione, l'espressione
cond ? ptr : 0restituiva un puntatore con un compilatore e int con un altro (dove 0 era interpretato rigorosamente come int). Il sistema andava in crash quando si tentava di utilizzare il risultato come puntatore.
Storia
In un pacchetto finanziario, dove le funzioni di ritorno utilizzavano l'operatore ternario con "litere" nude (
cond ? 0.0 : 1), il tipo del risultato era diventato imprudentemente double, anche se ci si aspettava un int, causando errori di confronto e stampa.
Storia
In una delle librerie avveniva una chiamata con un'espressione che aveva effetti collaterali:
flag ? inc(x) : dec(x). Durante il refactoring è emerso un errore nascosto: entrambe le espressioni chiamavano una funzione (con i propri effetti collaterali), mentre ci si aspettava che ne venisse eseguita solo una. La confusione con macro annidate ha portato a una doppia modifica del valore, che è stata scoperta solo durante i test dettagliati.