【发布时间】:2013-06-28 07:38:27
【问题描述】:
在 C++11 标准的上下文中(如你所知,它不再有序列点的概念)我想了解两个最简单的示例是如何定义的。
int i = 0;
i = i++; // #0
i = ++i; // #1
有两个关于 SO 的主题解释了 C++11 上下文中的这些示例。 Here 据说 #0 调用 UB 并且 #1 定义明确。 Here 据说这两个例子都是未定义的。这种模棱两可让我很困惑。我已经将这篇结构良好的reference 阅读了三遍,但这个主题对我来说似乎太复杂了。
.
我们来分析例子#0:i = i++;。
相应的引号是:
内置postincrement和postdecrement的值计算 运算符在其副作用之前排序。
内置的副作用(左参数的修改) 赋值运算符和所有内置的复合赋值运算符 在值计算(但不是副作用)之后排序 左右参数,并在值之前排序 赋值表达式的计算(即在返回之前 对修改对象的引用)
如果标量对象的副作用相对于另一个对象是未排序的 对同一标量对象的副作用,行为未定义。
据我所知,赋值运算符的副作用与左右参数的副作用没有顺序。因此赋值运算符的副作用与i++ 的副作用没有顺序。所以#0 调用了一个 UB。
.
我们来分析例子#1:i = ++i;。
相应的引号是:
内置预增量和预减量的副作用 运算符在其值计算之前排序(由于隐含规则 定义为复合赋值)
内置的副作用(左参数的修改) 赋值运算符和所有内置的复合赋值运算符 在值计算(但不是副作用)之后排序 左右参数,并在值之前排序 赋值表达式的计算(即在返回之前 对修改对象的引用)
如果标量对象的副作用相对于另一个对象是未排序的 对同一标量对象的副作用,行为未定义。
我看不出,这个例子与#0 有何不同。出于与#0 相同的原因,这对我来说似乎是一个 UB。赋值的副作用与++i 的副作用没有先后顺序。好像是个UB。上面喜欢的主题说它定义明确。为什么?
.
问题:如何应用引用规则来确定示例的 UB。一个尽可能简单的解释将不胜感激。谢谢!
【问题讨论】:
-
如果我在生产代码中看到这一点,我会与程序员进行一次非常坦率的对话。是的,这是一种智力上的好奇心,但在思考这个问题时看不到太多好处。也就是说,对于写得很好的问题+1,我将详细阅读已接受的答案。
-
@Bathsheba 我同意这些代码示例可能永远不会出现在真实代码中,但我认为对标准的理解将有助于确定其他示例中的 UB。
-
我对你的问题质量表示赞同,并且和你一样,等待类似质量的答案。
-
@Bathsheba 谢谢你,希望我们能在这里看到一些全面的解释。
-
讨论完成后请有人将其添加到社区答案中
标签: c++ c++11 sequence increment undefined-behavior