The C++11 standard(5.17,expr.ass)声明
在所有情况下,在计算值之后对赋值进行排序 左右操作数,以及值的计算之前 赋值表达式。关于 不确定顺序的函数调用,化合物的操作 赋值是一个单一的评估
这是否意味着表达式:
int a = 1, b = 10;
int c = (a+=1) + (b+=1);
if ( c == 10+1+1+1 ) {
printf("this is guaranteed");
} else {
printf("not guaranteed");
}
将始终评估为c==23
?
答案 0 :(得分:2)
表达式
int c = (a+=1) + (b+=1);
(编辑:添加了缺少的括号,我认为这是你的意图)
具有以下子表达式
(1) a+=1
(2) b+=1
(3) (1)+(2)
(4) c = (3)
未指定评估(1)和(2)的顺序,编译器可以自由选择它喜欢的任何顺序。
编译器可以在评估之前评估(1)和(2)。
(3)必须在之前进行评估编译器可以评估(4)。
现在,由于(1)和(2)的评估顺序无关紧要,整体结果已明确定义,您的代码将始终生成13
并打印“这是现在的标准”。请注意,这一直是这样,这对于C ++ 11来说并不新鲜。
答案 1 :(得分:1)
在您的示例中,编译器应发出错误,因为加法运算符的优先级高于赋值运算符的优先级。因此,首先计算1 + b,然后尝试将1分配给表达式(1 + b),但(1 + b)不是左值。
答案 2 :(得分:1)
这始终得到保证,并且在规则之前排序
(或者在C ++ 11之前的序列点规则)不需要
确定这个。在C ++中,每个(子)表达式都有两个重要的表达式
生成的代码中的效果:它有一个值(除非它是
键入void
),它可能有副作用。按顺序排列
之前/序列点规则会影响副作用
保证已经发生;它们对价值没有影响
子表达式。在您的情况下,例如,值
(a += 1)
的{{1}}是赋值后的a
值,
无论实际分配何时发生。
在C ++ 11中,保证a
的实际修改
修改c
之前的地方;在预C ++ 11中,没有
关于订单的保证。然而,在这种情况下,存在
合规程序无法看到这种差异,所以它
无所谓。 (在像c = (c += 1)
这样的情况下,这很重要,
这在前C ++ 11中将是未定义的行为。)