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); }