问题
I have a piece of code in C given as follows :
main()
{
int a=10, b;
a>=5 ? b=100 : b=200 ;
printf("%d" , b);
}
running the code on gcc compiler in unix generates the compile-time error as 'lvalue required as left operand of assignment' and points the error at b = 200 whereas in windows compiling using Turbo C gives 200 as output.
Can anybody please explain what exactly is happening in this case ?
回答1:
In C the ternary operator is defined like
logical-OR-expression ? expression : conditional-expression
where conditional expression is defined like
logical-OR-expression
The assignment operator has a lower priority than the OR operator. Thus you have to write
a >= 5 ? b = 100 : ( b = 200 );
Otherwise the compiler consideres the expression like
( a >= 5 ? b = 100 : b ) = 200;
As the result of the ternary operator in C is not an lvalue then the above expression is invalid and the compiler issues an error.
From the C Standard:
the result is the value of the second or third operand (whichever is evaluated), converted to the type described below
and footnote:
110) A conditional expression does not yield an lvalue.
Take into account that there is an essential difference between the operator definition in C and C++. In C++ it is defined as
logical-or-expression ? expression : assignment-expression
In C++ the same GCC compiles the code successfully
#include <iostream>
int main()
{
int a = 10, b;
a >= 5 ? b = 100 : b = 200;
std::cout << "b = " << b << std::endl;
return 0;
}
回答2:
you can put it in braces for it to work.. like
(a>=5)?(b=100):(b=200);
and please assign a return type for your function main()
回答3:
This error is caused by the syntax of the conditional-expression which is
logical-OR-expression ? expression : conditional-expression
Therefore, the part after :
must be able to parse b = 200
. However, conditional-expression
cannot parse that, because an assignment expression has less precedence - you would need to put a parenthesis around the assignment expression
a>=5 ? b=100 : (b=200);
But the fact that you need a parenthesis here does not mean that the expression otherwise is parsed as (a>=5 ? b=100 : b) = 200
, it is just a compiler's internal artefact that in the error message it talks about the left operand of assignment. The C language has the following two rules for the assignment expression syntax, and the rule that matches is applied
conditional_expression
unary_expression '=' assignment_expression
This interferes with recursive descent parsers, that would simply invoke parseConditionalExpression
, and check what token follows. Therefore some C parser implementations choose to not give a syntax error here, but parse it as though the grammar said conditional_expression '=' ...
above, and later when inspecting the parse tree, validate that the left hand side is an lvalue. For example, the 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's 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. */
回答4:
The parentheses should be around the condition in this case.
(a>=5) ? b=100 : b=200;
should compile correctly
RE: K&R The C Programming Language (2nd):
Parentheses are not necessary around the first expression of a conditional expression, since the precedence of ?:
is very low, just above assignment. (emphasis mine) They are advisable anyway, however, since they make the condition part of the expression easier to see.
回答5:
Try this one! Because the ternary operator returns the value you have to assgin it to b
!
#include <stdio.h>
main() {
int a = 10, b;
b = a >= 5 ? 100 : 200;
printf("%d" , b);
}
来源:https://stackoverflow.com/questions/26448611/errors-using-ternary-operator-in-c