There are several possibilities to do an endless loop, here are a few I would choose:
for(;;) {}
while(1) {}
/ while(true) {}
do {} while(1)
/ do {} while(true)
Is there a certain form which one should choose? And do modern compilers make a difference between the middle and the last statement or does it realize that it is an endless loop and skips the checking part entirely?
Edit: as it has been mentioned I forgot goto
, but this was done out of the reason that I don't like it as a command at all.
Edit2: I made some grep on the latest versions taken from kernel.org. I does seems as nothing much changed over time (within the Kernel at least)
This question is related to
c++
c
loops
infinite-loop
I would recommend while (1) { }
or while (true) { }
. It's what most programmers would write, and for readability reasons you should follow the common idioms.
(Ok, so there is an obvious "citation needed" for the claim about most programmers. But from the code I've seen, in C since 1984, I believe it is true.)
Any reasonable compiler would compile all of them to the same code, with an unconditional jump, but I wouldn't be surprised if there are some unreasonable compilers out there, for embedded or other specialized systems.
Is there a certain form which one should choose?
You can choose either. Its matter of choice. All are equivalent. while(1) {}/while(true){}
is frequently used for infinite loop by programmers.
In an ultimate act of boredom, I actually wrote a few versions of these loops and compiled it with GCC on my mac mini.
the
while(1){}
and for(;;) {}
produced same assembly results
while the do{} while(1);
produced similar but a different assembly code
heres the one for while/for loop
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## @main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
movl $0, -4(%rbp)
LBB0_1: ## =>This Inner Loop Header: Depth=1
jmp LBB0_1
.cfi_endproc
and the do while loop
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 4, 0x90
_main: ## @main
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
movl $0, -4(%rbp)
LBB0_1: ## =>This Inner Loop Header: Depth=1
jmp LBB0_2
LBB0_2: ## in Loop: Header=BB0_1 Depth=1
movb $1, %al
testb $1, %al
jne LBB0_1
jmp LBB0_3
LBB0_3:
movl $0, %eax
popq %rbp
ret
.cfi_endproc
It is very subjective. I write this:
while(true) {} //in C++
Because its intent is very much clear and it is also readable: you look at it and you know infinite loop is intended.
One might say for(;;)
is also clear. But I would argue that because of its convoluted syntax, this option requires extra knowledge to reach the conclusion that it is an infinite loop, hence it is relatively less clear. I would even say there are more number of programmers who don't know what for(;;)
does (even if they know usual for
loop), but almost all programmers who knows while
loop would immediately figure out what while(true)
does.
To me, writing for(;;)
to mean infinite loop, is like writing while()
to mean infinite loop — while the former works, the latter does NOT. In the former case, empty condition turns out to be true
implicitly, but in the latter case, it is an error! I personally didn't like it.
Now while(1)
is also there in the competition. I would ask: why while(1)
? Why not while(2)
, while(3)
or while(0.1)
? Well, whatever you write, you actually mean while(true)
— if so, then why not write it instead?
In C (if I ever write), I would probably write this:
while(1) {} //in C
While while(2)
, while(3)
and while(0.1)
would equally make sense. But just to be conformant with other C programmers, I would write while(1)
, because lots of C programmers write this and I find no reason to deviate from the norm.
I use for(;/*ever*/;)
.
It is easy to read and it takes a bit longer to type (due to the shifts for the asterisks), indicating I should be really careful when using this type of loop. The green text that shows up in the conditional is also a pretty odd sight—another indication this construct is frowned upon unless absolutely necessary.
They probably compile down to nearly the same machine code, so it is a matter of taste.
Personally, I would chose the one that is the clearest (i.e. very clear that it is supposed to be an infinite loop).
I would lean towards while(true){}
.
They are the same. But I suggest "while(ture)" which has best representation.
Well, there is a lot of taste in this one. I think people from a C background are more likely to prefer for(;;), which reads as "forever". If its for work, do what the locals do, if its for yourself, do the one that you can most easily read.
But in my experience, do { } while (1); is almost never used.
Everyone seems to like while (true)
:
https://stackoverflow.com/a/224142/1508519
https://stackoverflow.com/a/1401169/1508519
https://stackoverflow.com/a/1401165/1508519
https://stackoverflow.com/a/1401164/1508519
https://stackoverflow.com/a/1401176/1508519
According to SLaks, they compile identically.
Ben Zotto also says it doesn't matter:
It's not faster. If you really care, compile with assembler output for your platform and look to see. It doesn't matter. This never matters. Write your infinite loops however you like.
In response to user1216838, here's my attempt to reproduce his results.
Here's my machine:
cat /etc/*-release
CentOS release 6.4 (Final)
gcc version:
Target: x86_64-unknown-linux-gnu
Thread model: posix
gcc version 4.8.2 (GCC)
And test files:
// testing.cpp
#include <iostream>
int main() {
do { break; } while(1);
}
// testing2.cpp
#include <iostream>
int main() {
while(1) { break; }
}
// testing3.cpp
#include <iostream>
int main() {
while(true) { break; }
}
The commands:
gcc -S -o test1.asm testing.cpp
gcc -S -o test2.asm testing2.cpp
gcc -S -o test3.asm testing3.cpp
cmp test1.asm test2.asm
The only difference is the first line, aka the filename.
test1.asm test2.asm differ: byte 16, line 1
Output:
.file "testing2.cpp"
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.text
.globl main
.type main, @function
main:
.LFB969:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
nop
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE969:
.size main, .-main
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB970:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L3
cmpl $65535, -8(%rbp)
jne .L3
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
call __cxa_atexit
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE970:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB971:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $65535, %esi
movl $1, %edi
call _Z41__static_initialization_and_destruction_0ii
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE971:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .ctors,"aw",@progbits
.align 8
.quad _GLOBAL__sub_I_main
.hidden __dso_handle
.ident "GCC: (GNU) 4.8.2"
.section .note.GNU-stack,"",@progbits
With -O3
, the output is considerably smaller of course, but still no difference.
The idiom designed into the C language (and inherited into C++) for infinite looping is for(;;)
: the omission of a test form. The do/while
and while
loops do not have this special feature; their test expressions are mandatory.
for(;;)
does not express "loop while some condition is true that happens to always be true". It expresses "loop endlessly". No superfluous condition is present.
Therefore, the for(;;)
construct is the canonical endless loop. This is a fact.
All that is left to opinion is whether or not to write the canonical endless loop, or to choose something baroque which involves extra identifiers and constants, to build a superfluous expression.
Even if the test expression of while
were optional, which it isn't, while();
would be strange. while
what? By contrast, the answer to the question for
what? is: why, ever---for ever! As a joke some programmers of days past have defined blank macros, so they could write for(ev;e;r);
.
while(true)
is superior to while(1)
because at least it doesn't involve the kludge that 1 represents truth. However, while(true)
didn't enter into C until C99. for(;;)
exists in every version of C going back to the language described in the 1978 book K&R1, and in every dialect of C++, and even related languages. If you're coding in a code base written in C90, you have to define your own true
for while (true)
.
while(true)
reads badly. While what is true? We don't really want to see the identifier true
in code, except when we are initializing boolean variables or assigning to them. true
need not ever appear in conditional tests. Good coding style avoids cruft like this:
if (condition == true) ...
in favor of:
if (condition) ...
For this reason while (0 == 0)
is superior to while (true)
: it uses an actual condition that tests something, which turns into a sentence: "loop while zero is equal to zero." We need a predicate to go nicely with "while"; the word "true" isn't a predicate, but the relational operator ==
is.
All are going to perform same function, and it is true to choose what you prefer.. i might think "while(1) or while(true)" is good practice to use.
Source: Stackoverflow.com