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