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

我刚刚决定将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

根据2005年的GCC补丁 ,似乎GCC正在执行“不安全的循环优化”(并且由于-funsafe-loop-optimizations安全环路优化,因此您会-funsafe-loop-optimizations警告)。 如果循环无限的,则此特定优化将以某种方式失败。

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

补丁的另一个相关部分:

 @opindex Wunsafe-loop-optimizations
如果由于编译器无法优化循环,则发出警告
假设循环索引的边界上有任何东西。 同
 @option {-funsafe-loop-optimizations}警告编译器是否成功
 +这样的假设。

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

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

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

它主要用于:

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

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

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

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

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