Errors using ternary operator in c

I have a piece of code in C listed below:

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

running code in the gcc compiler on unix generates a compile-time error like 'lvalue, required as the left assignment operand', and indicates an error at b = 200, while when compiling Windows using Turbo C, it returns 200 as output.

Can someone explain what exactly happens in this case?

+6
source share
4 answers

In C, the ternary operator is defined as

boolean-OR-expression? expression: conditional expression

where the conditional expression is defined as

 logical-OR-expression 

The assignment operator has a lower priority than the OR operator. So you should write

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

Otherwise, the compiler takes into account an expression like

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

As a result of the ternary operator in C is not an lvalue, then the above expression is not valid, and the compiler throws an error.

From standard C:

the result is the value of the second or third operand (depending on what is evaluated), is converted to the type described below

and footnote:

110) The conditional expression does not give an lvalue.

Keep in mind that there is a significant difference between the definition of an operator in C and C ++. In C ++, it is defined as

boolean or expression? expression: assignment-expression

In C ++, the same GCC successfully compiles code

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

you can put it in braces to make it work .. kind of

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

and assign a return type to your main() function

+2
source

This error is caused by the conditional expression syntax, which

 logical-OR-expression ? expression : conditional-expression 

Therefore, the part after : should be able to parse b = 200 . However, conditional-expression cannot parse this, since an assignment expression has a lower priority - you need to put brackets around the assignment expression

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

But the fact that you need a bracket here does not mean that the expression is otherwise parsed as (a>=5 ? b=100 : b) = 200 , it’s just an internal compiler artifact that says left in the error message operand assignment. The C language has the following two rules for the syntax of an assignment expression, and a rule that matches

 conditional_expression unary_expression '=' assignment_expression 

This gets in the way of recursive parsers that simply call parseConditionalExpression and check what the token means. Therefore, some implementations of the C syntax do not give a syntax error here, but analyze it as if the grammar said conditional_expression '=' ... above, and later when checking the parsing tree, confirm that the left side is lvalue. For example, Clang source code says

 /// 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. 

And the GCC parser source code says

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

Try it! Since the ternary operator returns the value you must execute, b !

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

Source: https://habr.com/ru/post/976933/


All Articles