What is the explanation for “warning: assuming tha

2020-07-02 11:46发布

问题:

I had just taken the decision to change as many variables from unsigned to int and upon recompiling the code in question, was greeted by this warning message:

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

The line in question:

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

This loop is 60 lines of code (inc white space/brackets etc), and has a goto within it, and at least one occurrence of continue.

In this case, I think I am appreciative that GCC is assuming this loop is not infinite, because, it should never loop indefinitely.

What is GCC trying to tell me here?

The grammar of the warning is almost suggestive that the warning should be taken within the context of some other warning, but there are none within that context.

[edit] It's all completely my own fault. I stole some optimization and warning options from a question on here somewhere without really understanding them, and had since forgotten about them.

See Mark Rushakoff's answer, and in addition, I have also used -Wunsafe-loop-optimizations to explicitly warn if GCC is making assumptions about a loop. See http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

回答1:

According to this GCC patch from 2005, it appears that GCC is performing an "unsafe loop optimization" (and you are being warned because -funsafe-loop-optimizations is set). If the loop is infinite, this particular optimization will fail somehow.

Since you said it is a terminating loop, it sounds as though you have nothing to worry about.

Another relevant part of the patch:

@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.


回答2:

The reason GCC warns you is because it have pulled of an unsafe optimization. Instead of

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

it basically uses:

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

which is correct only if endx+1 doesn't overflow, but this happens when endx is the largest possible value which means that x <= endx is always true. The compiler assumes that this doesn't happen.

The warning is sometimes a bit confusing because it's not actually the finiteness of the loop that is the point here. I don't know if there's a better candidate for a message that would be short enough for a compiler warning.

One example is the case where for example x and endx are integers the optimization could actually be interpreted as being allowed by the standard, if endx==MAX_INT you would have the condition being true which will lead to that x eventually overflows which is undefined behavior, this mean that the compiler may assume that this doesn't happen. To skip the loop entirely is a standard conforming behavior according to this interpretations.

Another case is if the program doesn't terminate during the loop or alters volatile memory (ie have observable behavior) which means that an infinite loop means undefined behavior (IIRC, at least the compiler is allowed to assume that this doesn't happen).



回答3:

I think that GCC is telling you that it can't determine that the loop is not infinite and is carrying on with compilation regardless. It's a warning, not an error, something you may want to think about.