(a=1)=2 是 C++98 中的未定义行为吗?

Is (a=1)=2 undefined behaviour in C++98?

类似代码,例如 (a+=1)%=7;,其中 a 是一个 int 变量。

我们知道运算符 +== 不是一个序列点,因此我们在两个相邻的序列点之间有两个副作用。 (我们这里使用的是cpp98的序列点规则)

但是,+== 等赋值运算符保证 return 左值 赋值后 ,这意味着执行顺序是在某种程度上 "defined".

那么这是未定义的行为吗?

(a=1)=2 在 C++11 之前是未定义的,因为 = 运算符没有引入序列点,因此 a 在没有插入序列点的情况下被修改了两次。同样适用于(a+=1)%=7

文本是:

Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.

值得一提的是,赋值运算符的描述有缺陷:

The result of the assignment operation is the value stored in the left operand after the assignment has taken place; the result is an lvalue.

如果结果是左值,则结果不能是存储值(那将是右值)。左值指定内存位置。这句话似乎暗示了一种顺序关系,但无论我们如何解释它,它都没有使用术语 "sequence point" 因此适用于前面关于序列点的文本。

如果说有什么不同的话,那就是该措辞让人对 (a=1) + 2 这样的表达方式产生了一些怀疑。排序的 C++11 修订版消除了所有这些歧义。