13

我刚刚决定将尽可能多的变量从unsignedtoint和重新编译有问题的代码时,受到以下警告消息的欢迎:

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

4

3 回答 3

13

根据this GCC patch from 2005,看来GCC正在执行“不安全的循环优化”(并且因为-funsafe-loop-optimizations已设置而被警告)。如果循环无限的,这个特定的优化会以某种方式失败。

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

补丁的另一个相关部分:

@opindex Wunsafe-loop-optimizations
如果由于编译器无法优化循环,则发出警告
假设任何在循环索引的范围内。和
@option{-funsafe-loop-optimizations} 如果编译器做出了警告
+这样的假设。
于 2010-06-05T23:25:24.580 回答
2

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,至少允许编译器假设这不会发生) .

于 2016-05-31T08:00:00.297 回答
0

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

于 2010-06-05T23:24:28.120 回答