What's the point of issuing a compiler warning for "while(true)" and not issuing one for "for(;;)"?
When I compile C++ code with Visual C++ 9 with "warning level 4" the following:
while( true ) {
//loop body with break on certain condition
}
开发者_运维技巧
and the following:
for( ; true; ) {
//same loop body
}
both trigger C4127: conditional expression is constant
warning but the following:
for( ; ; ) {
//same loop body
}
compiles without warning.
Why this difference, especially between the second and the third variant?
The reason for warning the user of constant conditional expressions is to help avoid bugs where the expression ends up being constant (for example, due to a typo). In the last case, there is no expression, so there is no risk of it accidentally being constant.
The reason is simple, though stupid.
It is important to diagnose infinite loop, but such might not be evident:
while(i >= 0) { --i; } // infinite if i unsigned
while(SOME_MACRO(i)) // err, depends on the expansion of macros
It is a great feature of a compiler to produce a warning for a tautological test, that is a test that turns out to be either always true or always false, because it's not obvious when it comes from a macro expansion or within a dependent context.
It just seems that VC++ pushed a bit too far here, and instead of considering tautological conditions warns for all true
or false
conditions it can find, even when they are already clearly stated in the code.
The for ( ;; )
construct is the canonical way to intentionally code an "endless" loop. I could imagine the compiler designers didn't want to generate a warning for that.
No point. After all, the langauge specification says ($6.5.3/2),
Either or both of the condition and the expression can be omitted. A missing condition makes the implied while clause equivalent to while(true).
So for ( ; ; )
is equivalent to while(true)
even according to the Standard. Therefore, I don't see any reason why the compiler should give warning in one case but not in the other!
--
If the compiler decides to give warning, then in my opinion, the compiler should give warning when the condition is missing as opposed to when it's present, so that the warning would be interpreted as hint for programmer to mention his intention clearly and explicitly.
I mean, for ( ;; )
is more likely to be a typo than the explicit mention of condition in for ( ;true; )
. The latter tells programmer's clear and explicit intent. As Steve says in comment:
For an int value y, char x = y is equivalent to char x = (char)y, but you might want a warning for an implicit narrowing conversion on the first but not the second.
So explicit intention should not receive warning, while implicit intention should receive!
Compiler warning are here to help catch potential bugs. Using an always true
condition in a while
loop is probably an error. For exemple, in the following code, this is probably a bug, and I'd like the compiler to warn me about it:
unsigned int x;
// ...
while (x >= 0) {
// ...
}
In such a situation, in optimized build the compiler will probably deduce that the condition is always true (since an unsigned integer cannot be smaller than 0). So there is a need for detection of an always true
condition in while
loop. I think that whoever wrote the detection of such an error didn't special case the while (true)
case, as there is a simple way to do a infinite loop with for (;;)
.
You can read here, how the decision to add a warning or not in Visual Studio, is taken (the exemple are about C#
but I suppose that the team has the same rule of thumb for warning in C++
).
精彩评论