c gcc turbo-c

Errores al usar el operador ternario en c



gcc turbo-c (5)

En C, el operador ternario se define como

expresión-OR-lógica? expresión: expresión condicional

donde la expresión condicional se define como

logical-OR-expression

El operador de asignación tiene una prioridad menor que el operador OR. Entonces tienes que escribir

a >= 5 ? b = 100 : ( b = 200 );

De lo contrario, el compilador considera la expresión como

( a >= 5 ? b = 100 : b ) = 200;

Como el resultado del operador ternario en C no es un valor l, la expresión anterior no es válida y el compilador emite un error.

Del estándar C:

el resultado es el valor del segundo o tercer operando (el que se evalúe), convertido al tipo que se describe a continuación

y nota al pie:

110) Una expresión condicional no produce un valor l.

Tenga en cuenta que existe una diferencia esencial entre la definición del operador en C y C ++. En C ++ se define como

¿lógica o expresión? expresión: asignación-expresión

En C ++, el mismo GCC compila el código con éxito

#include <iostream> int main() { int a = 10, b; a >= 5 ? b = 100 : b = 200; std::cout << "b = " << b << std::endl; return 0; }

Tengo un código en C dado de la siguiente manera:

main() { int a=10, b; a>=5 ? b=100 : b=200 ; printf("%d" , b); }

ejecutar el código en el compilador gcc en Unix genera el error en tiempo de compilación como "valor requerido como operando izquierdo de la asignación" y señala el error en b = 200 mientras que en la compilación de Windows usando Turbo C se obtiene 200 como salida.

¿Alguien puede explicar qué está sucediendo exactamente en este caso?


Este error es causado por la sintaxis de la expresión condicional que es

logical-OR-expression ? expression : conditional-expression

Por lo tanto, la parte posterior a : debe poder analizar b = 200 . Sin embargo, conditional-expression condicional no puede analizar eso, porque una expresión de asignación tiene menos precedencia; necesitaría poner un paréntesis alrededor de la expresión de asignación

a>=5 ? b=100 : (b=200);

Pero el hecho de que necesite un paréntesis aquí no significa que la expresión se analice de otro modo como (a>=5 ? b=100 : b) = 200 , es solo un artefacto interno del compilador que en el mensaje de error habla sobre el izquierda operando de asignación. El lenguaje C tiene las siguientes dos reglas para la sintaxis de expresión de asignación, y se aplica la regla que coincide

conditional_expression unary_expression ''='' assignment_expression

Esto interfiere con los analizadores de descenso recursivo, que simplemente invocarían parseConditionalExpression , y verificarían qué token sigue. Por lo tanto, algunas implementaciones de analizador de C eligen no dar un error de sintaxis aquí, sino analizarlo como si la gramática dijera conditional_expression ''='' ... arriba, y luego al inspeccionar el árbol de análisis, valide que el lado izquierdo sea un valor. Por ejemplo, el código fuente de Clang dice

/// Note: we diverge from the C99 grammar when parsing the assignment-expression /// production. C99 specifies that the LHS of an assignment operator should be /// parsed as a unary-expression, but consistency dictates that it be a /// conditional-expession. In practice, the important thing here is that the /// LHS of an assignment has to be an l-value, which productions between /// unary-expression and conditional-expression don''t produce. Because we want /// consistency, we parse the LHS as a conditional-expression, then check for /// l-value-ness in semantic analysis stages.

Y el código fuente del analizador GCC dice

/* ... In GNU C we accept any conditional expression on the LHS and diagnose the invalid lvalue rather than producing a syntax error. */


Los paréntesis deben estar alrededor de la condición en este caso.

(a>=5) ? b=100 : b=200; debe compilarse correctamente

RE: K&R The C Programming Language (2nd):

Los paréntesis no son necesarios alrededor de la primera expresión de una expresión condicional , ya que la precedencia de ?: Es muy baja, justo por encima de la asignación . (énfasis mío) Sin embargo, son aconsejables ya que hacen que la condición parte de la expresión sea más fácil de ver.


Prueba este! ¡Debido a que el operador ternario devuelve el valor, debe asignarlo a b !

#include <stdio.h> main() { int a = 10, b; b = a >= 5 ? 100 : 200; printf("%d" , b); }


puedes ponerlo entre llaves para que funcione ... como

(a>=5)?(b=100):(b=200);

y asigne un tipo de retorno para su función main()