如果(a)b=c,d=e,return;,为什么不编译
Why exactly this will not compile if (a) b = c, d = e, return;?
我沉迷于"braceles"if,比如:
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();
"逗号"运算符就是一个运算符。它的左侧和右侧必须是表达式,而return
不是表达式。
为了详细说明,逗号运算符首先计算其左侧,然后丢弃该值。然后,它计算其右侧,整个逗号表达式计算为右侧的值。
与此类似:
template <typename T, typename U>
U operator,(T t, U u)
{
return u;
}
因此,不能在逗号表达式中放入任何不是表达式本身的内容。
如果您希望同时执行一系列语句并将它们分组在一起,那么;
和{}
就是这样做的。没有理由在逗号运算符中重复这种行为。
可以通过以下方式完成
if (a) return ( b = c, d = e, 0 );
Oe如果没有返回表达式
if (a) return ( b = c, d = e, ( void )0 );
这是否回答了OP真正提出的问题,这可能是一个悬而未决的问题,但如果有人关心为什么逗号运算符是这样设计的,我认为它可以追溯到BCPL。
在BCPL中,您可以组合一系列任务,如:
L1 := R1
L2 := R2
转换为单个语句(命令),如:
L1, L2 := R1, R2
就像在C和C++中一样,这些都是按从左到右的顺序执行的。与C和C++不同,这个"逗号运算符"没有生成一个表达式(至少在C使用这个术语时是这样)。
BCPL还有一个resultis
,它可以让你把一组语句变成一个函数。
至少在我看来,在C中,Dennis1决定将这两个概念组合成一个更简单的概念:一个逗号运算符,可以连续计算多个表达式,并产生一个结果。
参考:BCPL参考手册
- 我想公平地说,我应该提到这个决定实际上是由Ken Thomson在B的设计中做出的。关于B的文件很少,几乎无法猜测
如前所述,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; }
,但如果您使用此答案顶部提到的语法,则可以避免此问题。它根本不可读,因为它没有语义意义。
无论如何,只有当b
和d
是全局变量时,这才有意义,例如errno
,允许您分配给变量并在一条语句中返回。
如果(a)b=c,d=e,return;,为什么不编译;?
这是因为逗号(,
)运算符的左操作数和右操作数必须是表达式。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.重点是我的
我在C中可以理解,但在C++中,如果没有与现有C代码的主要兼容性损失。
它本来可以,但为什么会有人希望它是?该语言已经包含了一种达到目的的方法——大括号。它们比像您那样滥用逗号运算符更可靠、更有用。例如,如果您正在使用UDT,那么当我重载逗号运算符时,您将遇到一些令人讨厌的意外。哎呀!
更重要的是,将return
作为表达式是没有意义的,因为函数在求值时已经返回,所以任何人都不可能使用任何假设的返回值。
你的整个问题都是基于你个人对牙套的厌恶。没有其他设计语言的人真的有这种感觉。