表达式的求值顺序一直是C++中未指定行为的来源。C++11标准是否最终规定了评估的顺序?
我们现在是否知道以下表达式的var1
值和var2
:
int var1 =10, var2=20;
var1 = var2 = 30;
是var1=30 and var2=30
,还是var1=20 and var2=30
?
不,新标准没有指定所有子表达式的计算顺序或顺序。
表达式a + b + c
在语法上被分组为(a + b) + c
,但是三个子表达式a
、b
和c
可以按任何顺序计算,并且计算不是相对于彼此排序的。
要使其更具体,请考虑:
int main()
{
return printf("Hello") + printf("World") + printf("n");
}
至于你的代码:那里没有歧义。它是一个表达式,形式为a = b
的赋值表达式,其中a
是左值var1
,b
是子表达式var2 = 30
。您想知道var1
最终是20
还是30
的事实使我相信您不确定运算符关联性(对于=
)。然而,这从来都不是模棱两可的,并且在我能想到的所有语言变体中都得到了很好的规定。同化运算符在右侧关联,导致我描述的子表达式a
和b
。该语言的这个(非常基本的)方面在C++11中没有改变。
如果你真的想把这两个问题结合起来,你应该考虑以下表达式:
var1 = 10;
(var1 = 20) = (var2 = var1);
现在最终表达式也是a = b
,但a
和b
都是非平凡的子表达式,其求值不是有序的。
var1 = var2 = 30;
两者都应30
,并由标准指定。没有指定的是,如果赋值操作数是复杂的表达式,必须在同量之前进行计算,那么计算它们的顺序是什么?
(expr1) = (expr2) = x;
1 2
or
(expr1) = (expr2) = x;
2 1
赋值运算符 (=) 和复合赋值运算符都从右到左分组。
这并没有告诉我们任何关于评估顺序的信息。它仅意味着a = b = c
被解析为a = (b = c)
而不是(a = b) = c
。
1.9/15
仍然适用:
排序除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的计算是无序的。
规则仅引入部分排序。在这样的表达式中:
(x+42) = (y+42)
保证在对 (x+42) 结果进行赋值之前执行子表达式 (x+42)
和 (y+42)
,但两个子表达式本身不会排序。任何一个都可以在另一个之前执行,甚至可以交错,并且在程序执行期间顺序不需要一致。