首页 > 解决方案 > (a=1)=2 在 C++98 中是未定义的行为吗?

问题描述

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

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

但是,赋值运算符喜欢+=or保证在 assignment 之后=返回左值,这意味着执行顺序在某种程度上是“定义的”。

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

标签: c++language-lawyerundefined-behaviorc++98sequence-points

解决方案


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

案文是:

在前一个和下一个序列点之间,一个标量对象的存储值最多只能通过表达式的评估修改一次。

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

赋值操作的结果是赋值后存储在左操作数中的值;结果是一个左值。

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

如果有的话,该措辞对诸如(a=1) + 2. 排序的 C++11 修订版消除了所有这些歧义。


推荐阅读