Disclaimer: I tried to search for similar question, however this returned about every C++ question... Also I would be grateful to anyone that could suggest a better title.
There are two eminent loop structure in C++: while
and for
.
do ... while
construct, it is kind of unparalleledstd::for_each
and BOOST_FOREACH
, but not every loop is a for each
Now, I may be a bit tight, but it always itches me to correct code like this:
int i = 0;
while ( i < 5)
{
// do stuff
++i; // I'm kind and use prefix notation... though I usually witness postfix
}
And transform it in:
for (int i = 0; i < 5; ++i)
{
// do stuff
}
The advantages of for
in this example are multiple, in my opinion:
I have a tendency therefore not to use while
, except perhaps for the while(true)
idiom but that's not something I have used in a while (pun intended). Even for complicated conditions I tend to stick to a for
construct, though on multiple lines:
// I am also a fan of typedefs
for (const_iterator it = myVector.begin(), end = myVector.end();
it != end && isValid(*it);
++it)
{ /* do stuff */ }
You could do this with a while
, of course, but then (1) and (2) would not be verified.
I would like to avoid 'subjective' remarks (of the kind "I like for/while better") and I am definitely interested to references to existing coding guidelines / coding standards.
EDIT:
I tend to really stick to (1) and (2) as far as possible, (1) because locality is recommended >> C++ Coding Standards: Item 18, and (2) because it makes maintenance easier if I don't have to scan a whole body loop to look for possible alterations of the control variable (which I takes for granted using a for
when the 3rd expression references the loop variables).
However, as gf
showed below, while do have its use:
while (obj.advance()) {}
Note that this is not a rant against while
but rather an attempt to find which one of while
or for
use depending on the case at hand (and for sound reasons, not merely liking).
Not all loops are for iteration:
while(condition) // read e.g.: while condition holds
{
}
is ok, while this feels forced:
for(;condition;)
{
}
You often see this for any input sources.
You might also have implicit iteration:
while(obj.advance())
{
}
Again, it looks forced with for.
Additionally, when forcing for
instead of while
, people tend to misuse it:
for(A a(0); foo.valid(); b+=x); // a and b don't relate to loop-control
Functionally, they're the same thing, of course. The only reason to differentiate is to impart some meaning to a maintainer or to some human reader/reviewer of the code.
I think the while idiom is useful for communicating to the reader of the code that a non-linear test is controlling the loop, whereas a for idiom generally implies some kind of sequence. My brain also kind of "expects" that for loops are controlled only by the counting expression section of the for statement arguments, and I'm surprised (and disappointed) when I find someone conditionally messing with the index variable inside the execution block.
You could put it in your coding standard that "for" loops should be used only when the full for loop construct is followed: the index must be initialized in the initializer section, the index must be tested in the loop-test section, and the value of the index must only be altered in the counting expression section. Any code that wants to alter the index in the executing block should use a while construct instead. The rationale would be "you can trust a for loop to execute using only the conditions you can see without having to hunt for hidden statements that alter the index, but you can't assume anything is true in a while loop."
I'm sure there are people who would argue and find plenty of counter examples to demonstrate valid uses of for statements that don't fit my model above. That's fine, but consider that your code can be "surprising" to a maintainer who may not have your insight or brilliance. And surprises are best avoided.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With