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

exe*_*ook 7 c++ compiler-errors operators

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

if (a) b++, c++, d = e; 
Run Code Online (Sandbox Code Playgroud)

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

main() {
    int a, b, c, d, e;
    if (a) b = c, d = e, return;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

while (a < 10) if (a == 5) half = a, save();
Run Code Online (Sandbox Code Playgroud)

App*_*les 23

"逗号"运算符正是运算符.它的左右两边必须是表达式,而return不是表达式.

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

它与此类似:

template <typename T, typename U>
U operator,(T t, U u)
{
    return u;
}
Run Code Online (Sandbox Code Playgroud)

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

如果你正在寻找能够同时一起执行一系列语句,并将它们组合的,这恰恰是;{}是.没有理由在逗号运算符中复制该行为.

  • @exebook我相信分号```很好地填补了这个角色.分号分隔表达式,括号`{}`连接它们. (2认同)
  • @DeadMG:首先,没人说.其次,"为什么语言是这样设计的"是次要问题.主要问题是它为什么不编译.这个问题回答了这个问题,它并没有说任何远程等同于"语句不能编译,因为语言是这样设计的". (2认同)

Vla*_*cow 6

它可以通过以下方式完成

if (a) return ( b = c, d = e, 0 );
Run Code Online (Sandbox Code Playgroud)

大江如果没有回归表达

if (a) return ( b = c, d = e, ( void )0 );
Run Code Online (Sandbox Code Playgroud)


Jer*_*fin 5

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

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

L1 := R1
L2 := R2
Run Code Online (Sandbox Code Playgroud)

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

L1, L2 := R1, R2
Run Code Online (Sandbox Code Playgroud)

与C和C++非常相似,这些按从左到右的顺序执行.与C和C++不同,这个"逗号运算符"没有产生单个表达式(至少在C使用该术语时).

BCPL还有一个resultis允许你将一个语句块写成几乎像函数的东西.

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

参考:BCPL参考手册


  1. 我想公平地说,我应该提一下这个决定实际上是由Ken Thomson在B的设计中做出的可能性.关于B的足够多的文件存活下来,几乎不可能猜到这一点.