0

表达式的求值顺序一直是 C++ 中未指定行为的来源。C++11 标准是否最终说明了评估的顺序应该是什么?

我们现在是否知道以下表达式的var1和的值:var2

int var1 =10, var2=20;
var1 = var2 = 30;

会是var1=30 and var2=30,还是var1=20 and var2=30

4

3 回答 3

7

不,新标准没有指定所有子表达式的计算顺序或排序。

该表达式a + b + c在语法上被分组为(a + b) + c,但三个子表达式ab并且c可以按任何顺序进行计算,并且计算彼此之间没有顺序。

为了使这一点更具体,请考虑:

int main()
{
    return printf("Hello") + printf("World") + printf("\n");
}

至于您的代码:那里没有歧义。它是一个表达式,形式为 的赋值表达式a = b,其中a是左值var1b是子表达式var2 = 30。您想知道var1最终是 as20还是 as的事实30使我相信您不确定运算符的关联性 (for =)。然而,这从来都不是模棱两可的,并且在我能想到的所有语言变体中都得到了很好的说明。赋值运算符在右侧关联,导致子表达式ab我所描述的。在 C++11 中,语言的这个(非常基础的)方面没有改变。

如果你真的想把这两个问题结合起来,你应该考虑下面的表达式:

var1 = 10;
(var1 = 20) = (var2 = var1);

现在最终表达式也是a = b,但两者ab都是非平凡的子表达式,其求值是无序的。

于 2013-10-25T08:38:06.383 回答
6
var1 = var2 = 30;

两者都应是30标准规定的。没有指定的是,如果分配操作数是复杂表达式,必须在分配之前进行评估,那么评估它们的顺序是什么?

(expr1) = (expr2) = x;
   1         2

or

(expr1) = (expr2) = x;
   2         1
于 2013-10-25T08:48:14.637 回答
3

赋值运算符 (=) 和复合赋值运算符都从右到左分组。

这并没有告诉我们任何有关评估顺序的信息。它仅仅意味着a = b = c被解析为a = (b = c)而不是(a = b) = c

1.9/15仍然适用:

除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的求值是无序的。

排序规则仅引入部分排序。在这样的表达式中:

(x+42) = (y+42)

保证在对 (x+42) 的结果赋值之前执行两个子表达式,但是这两个子表达式本身没有排序(x+42)(y+42)任何一个都可以在另一个之前执行,它们甚至可以交错,并且在程序执行期间顺序不需要保持一致。

于 2013-10-25T08:51:36.230 回答