我有这行代码:
front = (++front) % size;
在C中我没有收到任何警告但在C ++中我收到警告operation on front may be undefined [-Wsequence-point]
。这个preincrement用法如何导致未定义的行为?在我看来,这一行非常明确,将被解释为:
我的编译器是否只是发出一揽子警告?
P.S。如果我做front = front++;
或天堂禁止front = front++ + front++;
这样的事情,我理解警告。
编辑:此警告是在Windows 64上的CodeBlocks中使用GCC(tdm-1)4.6.1生成的
答案 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;