C ++ Perincrement Undefined Operation vs C.

时间:2014-10-30 18:31:52

标签: c++

我有这行代码:

front = (++front) % size;

在C中我没有收到任何警告但在C ++中我收到警告operation on front may be undefined [-Wsequence-point]。这个preincrement用法如何导致未定义的行为?在我看来,这一行非常明确,将被解释为:

  1. 增加前面
  2. mod front with size
  3. 为前线指定新值。
  4. 我的编译器是否只是发出一揽子警告?

    P.S。如果我做front = front++;或天堂禁止front = front++ + front++;这样的事情,我理解警告。

    编辑:此警告是在Windows 64上的CodeBlocks中使用GCC(tdm-1)4.6.1生成的

4 个答案:

答案 0 :(得分:5)

你在序列点之间改变前两次:一次通过++,一次通过赋值。 这是未定义的行为。

答案 1 :(得分:4)

在C ++ 11中,这是明确定义的;结构与:

相同
i = ++i + 1;

作为标准本身中明确定义的行为的示例。有关更详细的说明,请参阅AndreyT's answer here

在C ++ 03,C89和C99中,这是未定义的行为,因为它们对++i具有更宽松的排序规则。

答案 2 :(得分:3)

将递增的值写回front可以随时发生(在赋值修改front之前或之后),因此警告有效且代码不安全。

答案 3 :(得分:3)

旧的排序规则有边缘情况,其中操作顺序已明确定义但仍然是技术上未定义的行为。使用C ++ 11和C11,通过将序列点要求替换为'sequenced-before'和'sequenced-after'关系来解决这个问题。

你的例子就是这种情况。如果您在C11或C ++ 11模式下收到警告,则尚未针对新规则更新警告。在早期的C和C ++模式中,警告是正确的。如果你没有在早期模式中收到警告,那么它们根本就没有实现,那就没关系,因为“不需要诊断”。


与此同时,根据旧规则,这条线可以写得更清楚,也更正确:

front = (front + 1) % size;