views:

544

answers:

17

Looks like

while( condition ) {
    //do stuff
}

is completely equivalent to

for( ; condition; ) {
    //do stuff
}

Is there any reason to use the latter instead of the former?

+20  A: 

There's no good reason as far as I know. You're intentionally misleading people by using a for-loop that doesn't increment anything.

Update:

Based on the OP's comment to the question, I can speculate on how you might see such a construct in real code. I've seen (and used) this before:

lots::of::namespaces::container::iterator iter = foo.begin();
for (; iter != foo.end(); ++iter)
{
    // do stuff
}

But that's as far as I'll go with leaving things out of a for-loop. Perhaps your project had a loop that looked like that at one time. If you add code that removes elements of a container in the middle of the loop, you likely have to control carefully how iter is incremented. That could lead to code that looks like this:

for (; iter != foo.end(); )
{
    // do stuff

    if (condition)
    {
        iter = foo.erase(iter);
    }
    else
    {
        ++iter;
    }
}

However, that's no excuse for not taking the five seconds needed to change it into a while-loop.

Kristo
+1  A: 

if you want to do something a limited amount of times, then "for" let's you specify the constraint without jumbling it in with the logic inside your loop.

Evernoob
+3  A: 

As far as I know the two statements are optimized by the compiler into the same assember code anyway.. so no, there's no reason to do so - just personal preference.

Miky Dinescu
+2  A: 

In this case, I personally prefer the first loop as it is easier to write and read.

But if I have a loop that needs to some post statement, I'd use for loop like this:

for (; i < 10; i += 2)
leiz
+2  A: 

There might be small compiler-dependent differences on the assembly level, but ideally both should behave exactly the same, and the former is more readable. So no, no reson to use the latter version other than nonconformism.

suszterpatt
+2  A: 

Compile both and check the resulting disassembly, if they are the same (which they probably are). Choose the one you find most readable.

RA
+1  A: 

Keeping readability aside for a small while, there is usually no performance difference between the different loops. At least there is no significant difference.

For desktop applications you can chose based on Readability criteria. Refer to the other posts - e.g. looking at for loop someone thinks the incrementor is declared within the loop.

It seems for web applications e.g. client side scripting there might be a difference.

Check this site: http://www.websiteoptimization.com/speed/10/10-2.html

Run your own experiments and go by the results else stick by readability rules.

Sesh
Question explicitly asked about C++...
DevSolar
@sharptooth: And can I hold your wallet while you're running those experiments?
Mike Dunlavey
+3  A: 

It's possible to compile

for(INIT; CONDITION; UPDATE)
{
  BODY
}

into

{
  INIT
  while(CONDITION)
  {
    BODY
    UPDATE
  }
}

UPDATE: The seemingly redundant extra scope is to cage any variable definitions in INIT, i.e. from for(int i = 0; ...). Thanks!

It's basically just a reordering of the expressions. So there's no reason to prefer one over the other, for performance reasons. I would recommend while() if possible, since it's simpler. If a simpler construct expresses what you want to do, I think that's the one to use.

unwind
Remember that the `continue` statement has a different semantic in the latter case.
Juliano
Scope of INIT differs.
Kirill V. Lyadvinsky
Not only is it possible, it's also defined in the standard that way, see my answer to a duplicate of this question here: http://stackoverflow.com/questions/885908/while-1-vs-for-is-there-a-speed-difference/887298#887298.
Richard Corden
+1  A: 

I can see 2 reasons, none of which I'd consider:

  • Only have 1 loop construct, but then Kristo's objection stands
  • write "for (; EVER;)", but then prefer a LOOP_FOREVER macro if really want this.
stefaanv
Macros are evil. ;-)
DevSolar
`for (; EVER;)` == `while(true)` :)
suszterpatt
@suszterpatt It's reading "for ever".@DevSolar: what about BOOST_FOREACH?
stefaanv
+5  A: 

No. No. No.

Even if there were a microscopic performance difference, you'd have to be an end-stage Jedi performance tuner to have it matter enough to care.

Mike Dunlavey
And even if there were any performance difference, using the latter would still just be working around a compiler bug (failure to optimise the while loop).
Steve Jessop
+1 for "end-stage Jedi performance tuner"
DVK
Should be Sith performance tuner. As all code level optimizations like this are evil.
Martin York
@Martin: I suppose, but I have come down to situations where I've tuned the daylights out of an app, down to where tiny changes in the generated assembly code actually made a difference, but that's like wringing the last drop of "blood out of a turnip".
Mike Dunlavey
+1  A: 

There really is no difference in C-ish languages between a for (;cond;) loop and a while loop. Generally what I do in C-ish languages is start off writing the loop as a "for" and change it into a "while" if I end up with that form. It is kinda rare though, as you are always iterating through something, and C lets you put any code you want in that last area.

It would be different if C had real (pre-computed iteration) for loops.

T.E.D.
+2  A: 

I think "while" and "for" loops are meant for different idioms. The idiom of using "while" is "do something, while certain conditions are true". The idiom for "for" is "iterate over a certain range of elements"...

Whenever I read a code, I expect these idioms (and I think I am not alone). When I see "for" I understand, that someone is iterating over the certain range and I do not go into details. When I see the for cycle, used for another idiom (not the one, I expect), I get confused and have to go into details.

Anyway, it is very subjective...

SadSido
+6  A: 

Some compilers warn about constant loop conditions:

while (true) { /* ... */ } /* Warning! */
for (;;) { /* ... */ } /* No warning */

In the specific case of an infinite loop, I might choose a for loop over a while loop for that reason. But if the condition is not empty, I don't really see any benefit. My guess as to why it appeared in the mentioned project is that the code somehow evolved through maintenance, but was written in a more conventional way originally.

+1  A: 

You might want to use a do-while loop instead of a for loop so the code is processed at least once before conditions are checked and met (or not).

+4  A: 

Is there any reason to use the latter instead of the former?

  1. A misguided effort to impress your colleagues that you know that those two forms are equivalent.
  2. A foolish maneuver to ensure "job security" by making your code as confusing as possible so that no one will ever want to change it.
  3. The "w" key on your keyboard is broken.
  4. It started life as a for loop with initializers and incrementing condition, and when the logic changed, the developer was too busy to change it.
JohnMcG
+1 for #3! (add more characters to make it past 15)
David Thornley
+1  A: 

I used to write some pretty cryptic C/C++ code. Looking back, I would probably do this in a while loop:

ifstream f("file.txt");
char c;
for(f.get(c); !f.eof(); f.get(c)) {
  // ...
}

I guess my point is that for loops are usually shorter but less readable, if they're not used in the traditional sense of looping over a range.

jnylen
+1  A: 

This question has been answered - the language has a more natural construct for expressing what you want - you should use it. For example, I can certainly write this:

for (bool b = condition(); b; b = !b) {
    /* more code */
}

or:

while (condition()) {
    /* more code */
    break;
}

instead of the more conventional:

if (condition()) {
    /* more code */
}

But why? C (and all languages) have idioms and most of them make rational sense in terms of expressivity and expectation of meaning. When you dick with the idiom, your mess with the sensibilities of the person who has to read your code.

plinth