Errors using ternary operator in c

做~自己de王妃 提交于 2019-12-17 07:53:08

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!