“警告:假设循环不是无限”的解释是什么?

时间:2010-06-05 23:20:34

标签: c gcc gcc-warning

我刚刚决定将unsigned中的变量更改为int,并在重新编译相关代码时受到此警告消息的欢迎:

freespace_state.c:203: warning: assuming that the loop is not infinite

有问题的一行:

for (x = startx; x <= endx; ++x, ++xptr)

这个循环是60行代码(包括空格/括号等),其中包含goto,并且至少出现一次continue

在这种情况下,我认为我很欣赏GCC假设这个循环不是无限的,因为它永远不应该无限循环。

GCC试图在这里告诉我什么?

警告的语法几乎暗示警告应该在其他警告的范围内进行,但在该情况下没有警告。

[编辑] 这完全是我自己的错。我从这里的某个问题偷了一些优化和警告选项而没有真正理解它们,并且忘记了它们。

请参阅Mark Rushakoff的回答,此外,我还使用-Wunsafe-loop-optimizations明确警告GCC是否对循环做出假设。见http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

3 个答案:

答案 0 :(得分:13)

根据this GCC patch from 2005,似乎GCC正在执行“不安全的循环优化”(并且因为设置了-funsafe-loop-optimizations而您正在收到警告)。如果循环 无限,则此特定优化将以某种方式失败。

由于你说这是一个终止循环,听起来好像你没什么可担心的。

补丁的另一个相关部分:

@opindex Wunsafe-loop-optimizations
Warn if the loop cannot be optimized because the compiler could not
assume anything on the bounds of the loop indices.  With
@option{-funsafe-loop-optimizations} warn if the compiler made
+such assumptions.

答案 1 :(得分:0)

我认为GCC告诉你它不能确定循环不是无限的,并且无论如何都在进行编译。这是一个警告,而不是错误,你可能想要考虑的事情。

答案 2 :(得分:0)

GCC警告你的原因是因为它已经引发了不安全的优化。而不是

for (x = startx; x <= endx; ++x, ++xptr)

它基本上使用:

for( x = startx; x < (endx+1); ++x, ++xptr)

仅当endx+1没有溢出时才是正确的,但是当endx是最大可能值时会发生这种情况,这意味着x <= endx始终为真。编译器认为这不会发生。

警告有时会让人感到困惑,因为它实际上并不是循环的有限性。我不知道是否有更好的候选消息,这些消息对于编译器警告来说足够短。

一个例子是例如xendx是整数,优化实际上可以被解释为标准允许的情况,如果endx==MAX_INT你的条件是真的这将导致x最终溢出,这是未定义的行为,这意味着编译器可能会认为这不会发生。根据这种解释,完全跳过循环是一种标准的符合行为。

另一种情况是程序在循环期间没有终止或改变易失性存储器(即具有可观察的行为),这意味着无限循环意味着未定义的行为(IIRC,至少允许编译器假设这个不会发生。)