gcc 在c#中使用三元运算符时出错

tquggr8v  于 2022-11-13  发布在  C#
关注(0)|答案(5)|浏览(143)

我有一段C语言的代码,如下所示:

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

在Unix中的gcc编译器上运行代码会生成编译时错误“左值需要作为赋值的左操作数”,并将错误指向B = 200,而在Windows中使用Turbo C进行编译时,输出为200。
有人能解释一下这个案子到底发生了什么吗?

krcsximq

krcsximq1#

在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 <iostream>

int main() 
{
    int a = 10, b;

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

    std::cout << "b = " << b << std::endl;

    return 0;
}
raogr8fs

raogr8fs2#

你可以把它放在括号里让它工作..就像

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

请为函数main()指定返回类型

cclgggtu

cclgggtu3#

此错误是由条件表达式的语法引起的,该语法为

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,然后检查后面跟着什么标记。因此,一些C解析器实现选择不在这里给予语法错误,而是按照上面的语法conditional_expression '=' ...进行解析,然后在检查解析树时,验证左手是左值。例如,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. */
4dbbbstv

4dbbbstv4#

在这种情况下,应将条件括在括号中。
(a>=5) ? b=100 : b=200;应能正确编译
RE: K&R The C Programming Language (2nd):
在 * 条件表达式 * 的第一个表达式周围没有必要使用括号,因为?:的优先级非常低,就在赋值之上。(着重号是我的)然而,无论如何,使用括号是可取的,因为它们使表达式的条件部分更容易看到。

kgsdhlau

kgsdhlau5#

试试这个!因为三元运算符返回的值是你必须赋值给b的!

#include <stdio.h>

main() {

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

}

相关问题