写入新值是否构成预增量表达式“值计算”的一部分,还是“副作用”?

Lig*_*ica 5 c++ sequence-points language-lawyer c++11 c++17

考虑以下表达式(带有说明声明):

int n = 42;
--n &= 0x01;
Run Code Online (Sandbox Code Playgroud)

这是否违反排序规则?

在我看来,预自增是左操作数“值计算”的一部分。如果这是真的,那么从 C++11 开始,这里就不存在 UB(并且从 C++17 开始,值计算副作用都是相对于赋值进行排序的)。

如果它是后置增量,那么 的修改n将仅仅是一个副作用,并且我们不会有良好的排序(直到 C++17)。

bar*_*top 3

我想你是对的,标准是这样说的:

8.5.18 赋值和复合赋值运算符

所有这些都需要一个可修改的左值作为其左操作数;它们的结果是引用左操作数的左值。[...] 在所有情况下,赋值都是在右操作数和左操作数的值计算之后、赋值表达式的值计算之前进行排序的。

所以从上面看来,赋值是值表达式,赋值的左边和右边都在赋值之前进行评估。

根据关于预增量的标准:

8.5.2.2 递增和递减

结果是更新后的操作数;它是一个左值,如果操作数是一个位域,那么它也是一个位域。表达式 ++x 等价于 x+=1。

这意味着即使在 C++17 之前,其副作用也会在值计算之前排序。