2011-10-18 10 views
36

En el núcleo de Linux 3.0.4, mm/filemap.c tiene esta línea de código:uso extraño del operador condicional en Linux

retval = retval ?: desc.error; 

He intentado compilar un caso similar con una mínima prueba de gcc -Wall y no recibas ninguna advertencia; el comportamiento parece idéntica a:

retval = retval ? retval : desc.error; 

En cuanto a la norma C99, no puedo imaginar lo que describe formalmente este comportamiento. ¿Por qué está bien?

+9

Eche un vistazo a http://stackoverflow.com/questions/2806255/why-would-you-use-the-ternary-operator-without-assigning-a-value-for-the-true – vhallac

+3

Gracias, vhallac . Por lo que puedo decir, el uso de esta extensión GCC es un pequeño atajo que destruye por completo la portabilidad. –

+0

Exactamente lo que le dije a un colega que intentó usarlo en uno de nuestros proyectos. :) – vhallac

Respuesta

35

Como muchos otros han dicho, este es una extensión del CCG, que no forma parte de ningún estándar. Recibirá una advertencia si usa el interruptor -pedantic.

El puntode esta extensión no es realmente visible en este caso, pero imagina si en cambio, era

retval = foo() ?: desc.error; 

Con la extensión, foo() se llama sólo una vez. Sin él, debe introducir una variable temporal para evitar llamar al foo() dos veces.

+13

pero retval = foo(); retval = retval? retval: desc.error; es MUCHO mejor y es 100% portátil. – akappa

+0

Me gustó mucho la respuesta de David Given también, pero esta aclara la semántica de la evaluación única y me dice que '-pedantic' causa una advertencia. Elegido. –

+1

@akappa: No es mejor si prefiere evitar la introducción de variables temporales. Esta es una de las extensiones * realmente antiguas * de GCC, y refleja los gustos de lenguaje funcional de los desarrolladores originales de GCC. Además, en ese momento, todas las declaraciones de variables locales tenían que estar en la parte superior de la función; "declaraciones mixtas y código" no era estándar hasta C99. – zwol

3

Esta es una extensión específica de gcc para C y no es estándar.

7

Esta es una extensión llamada GCC Conditionals with Omitted Operands. Omitir el operando medio tiene el efecto de utilizar el valor del condicional como el operando omitido sin evaluarlo nuevamente. Es seguro de usar incluso si el condicional es una macro.

19

Es una extensión gcc. x ?: y es equivalente a x ? x : y --- ver http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals.

Sí, creo que es malo también.

+0

¿Por qué dices que es malo? No es portable, sí, pero tiene un efecto que no se puede obtener de ninguna otra manera (ver mi respuesta). – zwol

+0

¡No, no es malo! Es bastante útil – sidyll

+8

@Zack: es malo porque confunde a las personas que no conocen esa sintaxis no portátil e innecesaria. – akappa