如果(a)b = c,d = e,返回;?为什么这不会编译

时间:2013-12-24 18:02:49

标签: c++ compiler-errors operators

我沉迷于"无支撑" ifs,像这样:

if (a) b++, c++, d = e; 

但令人讨厌的是,return不能成为最后一部分的一部分。直觉上我觉得为什么会这样,但任何人都可以用编程语言来解释为什么这不会编译?

main() {
    int a, b, c, d, e;
    if (a) b = c, d = e, return;
}

如果你关心,请解释为什么这样设计,对我来说似乎是一个缺陷。我可以在C语言中理解,但在C ++中,它可以重新设计,而不会与现有的C代码造成严重的兼容性损失。

仅供比较:这些将编译并完成预期:

while (a < 10) a++, b--, c += 2;

while (a < 10) if (a == 5) half = a, save();

6 个答案:

答案 0 :(得分:23)

“逗号”运算符正是运算符。它的左侧和右侧必须是表达式,return不是表达式。

详细说明,逗号运算符首先计算其左侧,并丢弃该值。然后,它评估它的右侧,整个逗号表达式计算到右侧的值。

它与此类似:

template <typename T, typename U>
U operator,(T t, U u)
{
    return u;
}

因此,您不能在逗号表达式中放入任何不是表达式本身的内容。

如果您希望同时执行一系列语句并将它们组合在一起,那正是;{}的用语。没有理由在逗号运算符中复制该行为。

答案 1 :(得分:6)

可以通过以下方式完成

if (a) return ( b = c, d = e, 0 );

如果没有返回表达式

if (a) return ( b = c, d = e, ( void )0 );

答案 2 :(得分:5)

对于这是否能解决OP真正要求的问题,可能会有疑问,但是如果有人关心为什么逗号运算符的设计方式如此,我认为它可以追溯到BCPL。

在BCPL中,您可以组合一系列分配,例如:

L1 := R1
L2 := R2

...进入单个语句(命令),如:

L1, L2 := R1, R2

就像在C和C ++中一样,这些按从左到右的顺序执行。与C和C ++不同,这个“逗号运算符”没有产生单个表达式(至少在C使用该术语时)。

BCPL还有一个resultis,可以让你将一个语句块写成几乎像函数一样的东西。

至少对我而言,看起来在C中,Dennis 1 决定将这两个概念合并为一个相当简单的概念:逗号运算符,允许评估a连续的表达式数量,并产生一个结果。

参考:BCPL Reference Manual


  1. 我认为,公平地说,我应该提一下这个决定是由Ken Thomson在B的设计中实际做出的可能性。关于B的文件很少,幸存下来,几乎不可能猜到这一点。

答案 3 :(得分:3)

如前所述,return不是表达式,而是关键字。但是,b = c, d = e 表达式。因此你的意图可能就是:

if (a) return (b = c, d = e, 0);

b = c, d = e, return没有任何意义,因为它与逗号运算符在其他上下文中的工作方式不一致。想象一下,如果你能做到这一点:

for (int i = 0, j = 0, return; ...

这绝对没有意义。如果return在此上下文中有意义,因为逗号运算符已经返回其最后一个操作数,这也是多余的。也没有意义,因为逗号运算符已经评估了它的操作数,在这种情况下return something如何有益?

有人在查看你的代码时可能会看一眼并说“这应该是:if (a) (b = c, d = e); return 0;”,这是因为缺少括号而陷阱。它们的真正含义是if (a) { (b = c, d = e); return 0; },但如果您使用本答案顶部提到的语法,则可以避免此问题。它只是不可读,因为它没有语义意义。

无论如何,只有bd是全局变量(例如errno之类的东西)才有意义,允许您分配给变量并在一个语句中返回。

答案 4 :(得分:1)

  

如果(a)b = c,d = e,则返回;为什么这不会编译?

这是因为逗号(,)运算符的左右操作数必须为表达式return语句不是表达式。请参阅C和C ++标准为,运算符定义的语法:

C11:6.5.17逗号运算符

Syntax
      expression:
             assignment-expression
             expression , assignment-expression

C ++标准

定义了相同的语法

C ++:5.18逗号运算符[expr.comma]

  

逗号运算符从左到右分组。

      expression:
             assignment-expression
             expression , assignment-expression  
     

用逗号分隔的一对表达式 1 从左到右进行评估;

请注意,标准说明了表达式,而return不是表达式。


1.Emphasis is mine

答案 5 :(得分:0)

  

我可以在C语言中理解,但在C ++中,它可以在没有重新设计的情况下进行重新设计   与现有C代码的主要兼容性损失。

可以,但为什么有人会想要它呢?该语言已经包含了您正在寻找的最终方法。它们比滥用逗号运算符更可靠和有用。例如,如果你正在使用UDT,那么当我重载逗号运算符时,你会遇到一些令人讨厌的惊喜。糟糕!

更重要的是,将return作为表达式是没有意义的,因为在评估函数时函数已经很好地返回,因此任何人都无法使用任何假设的返回值

你的整个问题都取决于你个人对大括号的厌恶。没有其他人设计这种语言真的有这种感觉。