c中使用三元运算符的错误
我在C中有一段代码如下:
main() { int a=10, b; a>=5 ? b=100 : b=200 ; printf("%d" , b); }
在unix中运行gcc编译器上的代码会将编译时错误生成为’赋值左值所需的左值’,并将错误指向b = 200,而在使用Turbo C编译的窗口中,将200作为输出。
请问有谁可以解释一下这种情况究竟发生了什么?
在C中,三元运算符被定义为
逻辑OR表达? 表达式: 条件表达式
其中条件表达式定义为
logical-OR-expression
赋值运算符的优先级低于OR运算符。 因此你必须写
a >= 5 ? b = 100 : ( b = 200 );
否则编译器会考虑表达式
( a >= 5 ? b = 100 : b ) = 200;
由于C中的三元运算符不是左值,因此上述表达式无效,编译器发出错误。
从C标准:
结果是第二个或第三个操作数的值 (无论哪个被评估),转换为下面描述的类型
和脚注:
110)条件表达式不产生左值。
考虑到C和C ++中的运算符定义之间存在本质区别。 在C ++中,它被定义为
逻辑或表达? 表达式: 赋值表达式
在C ++中,相同的GCC成功编译代码
#include int main() { int a = 10, b; a >= 5 ? b = 100 : b = 200; std::cout << "b = " << b << std::endl; return 0; }
你可以把它放在支架上让它工作..就像
(a>=5)?(b=100):(b=200);
并请为您的函数main()
指定一个返回类型
此错误是由条件表达式的语法引起的
logical-OR-expression ? expression : conditional-expression
因此,后面的部分:
必须能够解析b = 200
。 但是, conditional-expression
无法解析它,因为赋值表达式的优先级较低 – 您需要在赋值表达式周围加上一个括号
a>=5 ? b=100 : (b=200);
但是这里你需要一个括号的事实并不意味着表达式否则被解析为(a>=5 ? b=100 : b) = 200
,它只是一个编译器的内部人工制品,它在错误信息中谈到了左派的操作数。 C语言对赋值表达式语法具有以下两个规则,并应用匹配的规则
conditional_expression unary_expression '=' assignment_expression
这会干扰递归下降解析器,它只会调用parseConditionalExpression
,并检查parseConditionalExpression
令牌。 因此,一些C语法分析器实现选择不在此处给出语法错误,但是解析它就好像语法上面的conditional_expression '=' ...
上面一样,稍后在检查解析树时,validation左侧是左值。 例如,Clang源代码说
/// 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.
GCC解析器的源代码说
/* ... In GNU C we accept any conditional expression on the LHS and diagnose the invalid lvalue rather than producing a syntax error. */
试试这个吧! 因为三元运算符返回值,你必须将它赋予b
!
#include main() { int a = 10, b; b = a >= 5 ? 100 : 200; printf("%d" , b); }