El operador condicional ternario (?:) permite calcular y devolver una de dos expresiones dependiendo de una condición:
result = cond ? expr_true : expr_false;
int a = 10, b = 0; int max = (a > b) ? a : b; // max = 10
"Si dos expresiones del operador ternario devuelven objetos de diferente tipo (por ejemplo, un puntero y cero), ¿cuál será el tipo de resultado?"
Muchos afirman que el compilador siempre "adivina" el tipo de resultado. En realidad, si una de las expresiones es un puntero y la otra es 0 o NULL, el resultado será de tipo puntero. Si la diferencia es más compleja — por ejemplo, un puntero de diferente tipo o un tipo int y un tipo enum — puede haber una pérdida de información no evidente, y a veces el compilador genera un error.
struct node *p = NULL; void *v = cond ? p : NULL; // ok void *z = cond ? p : 0; // ok int i = cond ? 0 : "abc"; // error: tipos incompatibles
Historia
En un gran proyecto de compilación cruzada, la expresión utilizada
cond ? ptr : 0devolvía un puntero con un compilador y un int con otro (donde 0 se interpretaba estrictamente como int). El sistema fallaba al intentar usar el resultado como puntero.
Historia
En un paquete financiero, donde las funciones de retorno utilizaban el operador ternario con literales "desnudos" (
cond ? 0.0 : 1), el tipo de resultado se volvió accidentalmente double, aunque se esperaba int, causando errores de comparación e impresión.
Historia
En una de las bibliotecas, se realizó una llamada con una expresión de efecto secundario:
flag ? inc(x) : dec(x). Durante la refactorización, surgió un error escondido: ambas expresiones llamaban a funciones (con sus propios efectos secundarios), aunque se esperaba que solo se ejecutara una. La confusión con macros anidadas llevó a un doble cambio de valor, que solo se detectó durante pruebas exhaustivas.