表达式的评估顺序一直是C ++中未指定行为的来源。 C ++ 11标准是否最终说明了评估的顺序应该是什么?
我们现在知道以下表达式的var1
和var2
的值:
int var1 =10, var2=20;
var1 = var2 = 30;
是var1=30 and var2=30
还是var1=20 and var2=30
?
答案 0 :(得分:7)
不,新标准没有指定所有子表达式的评估的排序或顺序。
表达式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
都是非平凡的子表达式,其评估不有序。
答案 1 :(得分:6)
var1 = var2 = 30;
两者都应为30
并且由标准指定。未指定的事情是,如果赋值操作数是复杂的表达式,必须在分配之前进行评估,那么评估它们的顺序是什么?
(expr1) = (expr2) = x;
1 2
or
(expr1) = (expr2) = x;
2 1
答案 2 :(得分:3)
赋值运算符(=)和复合赋值运算符从右到左分组。
这并没有告诉我们有关评估订单的任何信息。它仅表示a = b = c
被解析为a = (b = c)
而不是(a = b) = c
。
1.9/15
仍然适用:
除非另有说明,否则对单个操作符的操作数和单个表达式的子表达式的评估是不合理的。
排序规则仅引入部分排序。在这样的表达式中:
(x+42) = (y+42)
保证在(x + 42)的结果赋值发生之前执行子表达式(x+42)
和(y+42)
,但两个子表达式本身不是有序的。要么可以在另一个之前执行,它们甚至可以交错,并且在程序执行期间顺序不需要一致。