2012-04-05 24 views
5

Considere el siguiente fragmento de código:¿Uso válido del operador condicional?

int i, k, m; 
k = 12; 
m = 34; 
for (i = 0; i < 2; i++) ((i & 1) ? k : m) = 99 - i; 
printf("k: %ld m: %ld\n\n", k, m); 

En este tonto ejemplo, la expresión operador condicional es un atajo para:

if (i & 1) k = 99 - i; else m = 99 - i; 

Mi compilador no se queja y ejecución de esta pieza de código da salida esperada

k: 98 m: 99 

Mi pregunta, sin embargo, es si este es código válido de acuerdo con el estándar C? Nunca había visto algo así como antes.

+0

Si se compila y ejecuta como se esperaba, entonces lo más probable es válido. Sin embargo, debería preguntarse si desea mantener un código como ese, especialmente si no se toca durante algunos años y tiene que descifrar lo que hace cuando regresa 5 años en el futuro. –

Respuesta

8

Nota al pie 110 en el estándar C11:

una expresión condicional no produce un lvalue.

Y 6.5.16 párrafo 2:

un operador de asignación tendrá un valor-modificables como su operando izquierdo.

Así que no, ese código no cumple con el estándar C.

En C++ 11, que es válido:

Si el segundo y tercer operandos son lvalues ​​y tener el mismo tipo, el resultado es de ese tipo y es un lvalue.

Este es otro de esos rincones polvorientos donde C y C++ difieren significativamente. Si su compilador no produce un error, supongo que está utilizando un compilador de C++ con un "modo C", en lugar de un compilador de C apropiado; MSVC?

+1

Creo que es válido C++ sin embargo. – hugomg

+0

Estaba compilando como código C++, sí, no en "modo C" con MSVC++ 6.0. No he intentado compilarlo en modo C. Incluso si es válido, ya sea en C o en C++, ni siquiera tengo la intención de usarlo; fue solo algo que se me ocurrió mientras pensaba cómo codificar lo que quería que hiciera el programa y me dio curiosidad por su validez. ¡Gracias por su respuesta! – zarulad

+0

@zarulad: ¡contento de ayudar! –

1

Es válida para utilizar condicional como un lval en C++, pero no en C.

En C++ (ISO IEC 14882:? 1998 (E) 5.16.4)

Si el segundo y los terceros operandos son lvalues ​​y tienen el mismo tipo, el resultado es de ese tipo y es un valor l.

Si desea utilizar truco similar en C, que debe utilizar punteros:

ISO/IEC 9899: TC2, 6.5.14.6

Si ambos el segundo y tercer operandos son punteros o uno es una constante de puntero nulo y el otro es un puntero, el tipo de resultado es un puntero a un tipo calificado con todos los calificadores de tipo de los tipos apuntados por ambos operandos.

*((i & 1) ? &k : &m) = 99 - i; 
+0

¿Qué tal la cita de @StephenCanon? –

+0

@PavanManjunath Confundí C y C++ una vez más. Actualicé mi respuesta para reflejar eso. ¡Gracias! – dasblinkenlight

4

Esto no es legal C, y un compilador que lo acepta es incorrecto.Sin embargo, se puede hacer lo mismo con:

*((i & 1) ? &k : &m) = 99 - i; 

y se convierte en C legal