表达式的求值顺序一直是 C++ 中未指定行为的来源。C++11 标准是否最终说明了评估的顺序应该是什么?
我们现在是否知道以下表达式的var1
和的值:var2
int var1 =10, var2=20;
var1 = var2 = 30;
会是var1=30 and var2=30
,还是var1=20 and var2=30
?
表达式的求值顺序一直是 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
最终是 as20
还是 as的事实30
使我相信您不确定运算符的关联性 (for =
)。然而,这从来都不是模棱两可的,并且在我能想到的所有语言变体中都得到了很好的说明。赋值运算符在右侧关联,导致子表达式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)
任何一个都可以在另一个之前执行,它们甚至可以交错,并且在程序执行期间顺序不需要保持一致。