Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why do people write non-conditional loops as "for(;;)" instead of "while(1)"?


According to the C99 standard [0], an omitted optional expression-2 in a for loop is replaced by a non-zero constant. Thus, for(;;) is equivalent to for(;1;) which is effectively equivalent to while(1) as there are no other declarations or expressions. And, for those who are counting, it also saves a character.

[0] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf (See 6.8.5.3)


Why would anyone wreck legibility to save a character?


I don't think it wrecks legibility, since it's a C idiom. People reasonably experienced in C will read "for (;;)" as an infinite loop just as well as "while(1)". That said, it might be a little confusing for beginners (or others who don't use C very regularly).


Ahhh, the ole' semicolon debate.


Because while(1) evaluates to a constant, which can sometimes be a bug and thus, some compilers emit a warning.

http://msdn.microsoft.com/en-us/library/6t66728h%28v=vs.80%2...

http://stackoverflow.com/questions/3490823/why-msvc-generate...


So that you can do tricks like this:

    #define ever (;;)
    for ever {...}
;-)


Not applicable to the original article, but the reason I do it is because Go has no while loop. It doesn't require all those extra semis, though:

  for { 
    ...
  }


Because while(1) still has a condition that is checked on every loop iteration when optimizations are disabled. for(;;) can be read as "forever".


FWIW, GCC and Perl generate the same code for both.

http://stackoverflow.com/questions/885908/while-1-vs-for-is-...


Interesting. Looks like they'd be the same performance wise, since

for (;;);

is the same as

{ while (true) { ; ; } }

I originally asked this question cos it's used this way in first C program in the link. Bit of a tangent though :P


That issue disappeared before the 1980's. Check your compiler.


Any compiler/interpreter worth its salt will notice when an expression being tested in a conditional is constant and generate code that doesn't actually test it at run time. for (;;) is arguably more "idiomatic" C, though.


for(;;), being equivalent to for(;1;), also has that condition that has to be checked. So, it all boils down to how compilers treat the two.

And to add oil to the fire, here are some even 'better' ways to do this:

  do {
    ...
  } while(1);
At least that fits the common macro pattern "do{...}while(0)" (http://stackoverflow.com/questions/257418/do-while-0-what-is...).

Of course, all of these are inferior to:

  considered:
    ...
  goto considered;


I do doubt that even for a for(;;), a jmp (x86) is use instead of a conditional jump like jz.


Compilers are smart! For common things like this, they will easily optimise away any conditional jumps.


It is, you can easily check that yourself. for(;;) compiles to exactly one jmp in GCC (tested with gcc 4.7.0)


VC++ generates a warning with while(1) but not with for(;;). I just can't remember what warning level you need in order to see that distinction.


Why do people write while(1) instead of for(;;)? Are you saying that "while(1)" is superior in some way? Why?

I prefer "for(;;)" because it is explicitly defined as an infinite loop, but "while(1)" needs an implicit cast of "1" to "true", and even then there's an implicit test for "true".


True and false are actually defined as 1 and 0 respectively. I don't have a copy of the standard but this specifies true and false as macros.

http://pubs.opengroup.org/onlinepubs/007904975/basedefs/stdb...

Edit: Of course I'm talking about C here. Also, I prefer for(;;) because it's an easy to recognize idiom that means "infinite loop."


There's no casting involved in while(1). 1 is "true" in C, in fact, any integer != 0 is "true".

I just did a quick check and gcc -S produces the same ASM output for both of them, which doesn't include any comparisons whatsoever, just a jmp. So both of them are really compiled to an actual infinite loop.


I guess it's just personal preference. "for(;;)" looks really messy to me, and doesn't seem obvious that it signifies an infinite loop. I think that even the standard format for for loops (for (initialisation; condition; thing done at end of loop)) is quite unintuitive, and I have to think a bit to remember what each part does if one of them is omitted. It's also the only place I can think of where semicolons aren't expected at the end of a line (conventionally). I don't find a problem implicitly casting "1" to "true", I sort of do this automatically after programming in C for a while. Obviously if I were using java or something, I'd use "while(true)". Basically, I don't have to think much to know that it's an infinite loop :)


You could just say while(true). And I'm not sure that the test for true is implicit, since that is what while() explicitly does.


C doesn't have true / false as language constants, only as override-able macros.

The good thing is modern compilers can evaluate a loop and if the break condition is constant it can just do an infinite loop without checking.


It's 1 character shorter.... ;)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: