赋值子表达式的计算顺序
Order of evaluation of assignment subexpressions
C++11标准(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
?
表达式
int c = (a+=1) + (b+=1);
(编辑:添加了缺少的括号,我认为这就是您的意图)
具有以下子表达式
(1) a+=1
(2) b+=1
(3) (1)+(2)
(4) c = (3)
(1) 和 (2) 的计算顺序未指定,编译器可以自由选择它喜欢的任何顺序。
在编译器可以计算 (3) 之前,必须同时计算 (1) 和 (2)。
(3) 必须先求值,然后编译器才能求值 (4)。
现在,由于 (1) 和 (2) 的求值顺序无关紧要,总体结果已明确定义,您的代码将始终产生 13
并打印"现在是标准"。请注意,一直都是这样,这对 C++11 来说并不新鲜。
这一直是有保证的,并且在规则之前排序(或 C++11 之前)中的序列点规则不需要确定这一点。 在C++中,每个(子)表达式有两个重要的生成的代码中的影响:它有一个值(除非它是键入 void
),它可能有副作用。 已排序的之前/序列点规则影响副作用何时保证已经发生;它们对值没有影响的子表达式。 例如,在您的情况下,值(a += 1)
是a
赋值后将具有的值,无论实际分配何时发生。
在C++11中,a
的实际修改保证采取修改前的地方 c
;在 C++11 之前,没有关于订单的保证。 但是,在这种情况下,有符合标准的程序不可能看到这种差异,所以它无所谓。 (这在像c = (c += 1)
这样的情况下很重要,这将是 C++11 之前的未定义行为。
在您的示例中,编译器将发出错误,因为加法运算符的优先级高于赋值运算符的优先级。所以首先将计算 1 + b,然后尝试将 1 分配给表达式 (1 + b),但 (1 + b) 不是左值。
- 计算 I+V[i++] 的顺序是什么?
- 委派的 ctor 是否受参数计算顺序的影响?
- 函数参数计算顺序与 Lambda 捕获评估顺序
- 构造函数中初始化列表的计算顺序是否固定?
- 大括号和括号之间的参数计算顺序
- C++:cout 和函数调用之间的计算顺序
- 操作员 * 的计算顺序
- C++:计算顺序运算符时忽略括号
- C ,以下代码的计算顺序
- 使用参数和此关键字时的计算顺序
- 为什么在 c++ 中未指定函数参数的计算顺序
- 构造函数中成员启动列表的计算顺序
- C++嵌套的条件运算符计算顺序
- 赋值子表达式的计算顺序
- 初始化中的计算顺序
- 宏计算顺序
- C语言中等优先级操作数的计算顺序
- 移动语义和参数计算顺序
- 运算符优先级和计算顺序
- C++ 参数计算顺序