There are a number of places where the language of the Standard gives compilers freedoms beyond what are required for useful optimizations, but which would instead provide compilers with ways to throw the Principle of Least Astonishment out the window. The way the rules about endless loops are written fits that category.
Most of the optimizations which would be facilitated by the rules about endless loops would be enabled by language which specified that the time required to execute a section of code, even if infinite, is not considered to be a side-effect that compilers are required to preserve. Such a rule would allow a compiler to omit any loop iterations which don't have any direct side-effects and don't modify values that are used elsewhere.
The Standard, however, goes beyond that. Given the code:
int foo(void)
{
int x=0;
do
{
x=functionWithNoSideEffects(x);
} while(x != 23 && x != 42);
return x;
}
a compiler that could show that functionWithNoSideEffects would never have
any defined side-effects and would never return 23 could replace the code for "foo" with "return 42;". Even if the purpose of the program was to test whether functionWithNoSideEffects would ever return 42 (in which case having the generated code return 42 whether the function does or not would be unhelpful) the Standard would not require compilers to generate code to actually test that unless the loop included some kind of "side-effect".
I'm not personally convinced that the value of having a rule that says that
if compilers can show that a loop can't terminate without X being true, they
may regard X as being true whether or not there's any means by which it
could be. Optimizations based on that principle seem popular, however.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…