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()