“警告:假设循环不是无限”的解释是什么?
我刚刚决定将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
总是为真。 编译器假定这不会发生。
警告有时候有点令人困惑,因为它实际上并不是循环的有限性。 我不知道是否有一个更好的候选消息,这个消息对于编译器警告来说足够短。
一个例子是例如x
和endx
是整数的情况,优化实际上可以解释为标准允许,如果endx==MAX_INT
你将条件为真,这将导致x
最终溢出,这是未定义的行为,这意味着编译器可能会认为这不会发生。 根据这种解释,完全跳过循环是标准的符合行为。
另一种情况是程序在循环期间没有终止或改变易失性存储器(即具有可观察的行为),这意味着无限循环意味着未定义的行为(IIRC,至少允许编译器假设这不会发生) 。