When implementing an infinite loop, is there a dif

2019-01-11 10:14发布

问题:

When implementing an infinite loop, is there a difference in using while(1) vs for(;;) vs goto?

Thanks, Chenz

回答1:

They are equivalent, even if you turn the optimizer off.

Example:

#include <stdio.h>

extern void f(void) {
    while(1) {
        putchar(' ');
    }
}

extern void g(void) {
    for(;;){
        putchar(' ');
    }
}

extern void h(void) {
    z:
        putchar(' ');
    goto z;
}

Compile with gcc -O0 gives equivalent assembly for all 3 functions:

 f:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fb4 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fb8 00708DE2             add               r7,sp,#0x0
 +00008 00000fbc 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fc0 0A0000EB             bl                putchar (stub)
 +00010 00000fc4 FCFFFFEA             b                 loc_000008
 ;
 ;
 g:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fc8 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fcc 00708DE2             add               r7,sp,#0x0
 +00008 00000fd0 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fd4 050000EB             bl                putchar (stub)
 +00010 00000fd8 FCFFFFEA             b                 loc_000008
 ;
 ;
 h:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fdc 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fe0 00708DE2             add               r7,sp,#0x0
 +00008 00000fe4 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fe8 000000EB             bl                putchar (stub)
 +00010 00000fec FCFFFFEA             b                 loc_000008


回答2:

I just compared the unoptimized assembler output of gcc:

# cat while.c 
int main() {
    while(1) {};
    return 0;
}

# cat forloop.c 
int main() {
    for (;;) { };
    return 0;
}

Make assembler output:

# gcc -S while.c 
# gcc -S forloop.c 

Compare assembler files:

# diff forloop.s while.s
1c1
<   .file   "forloop.c"
---
>   .file   "while.c"

As you can see there are no significant differences. Here is the output

# cat while.s 
    .file   "while.c"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
.L2:
    jmp .L2                    # this is the loop in both cases
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

While this is not a technical proof that they are the same, I'd say it is in 99.9% of the cases.



回答3:

There is hardly any difference in generated assembly. It's more of an stylistic issue:

Goto - just ooogly: jumps backward, no explicit infinite block

while(1) - better, requires "dummy" condition though and you'll be often warned by compiler(warning level 4) or static analysis tool

for(;;) might not be the prettiest, but imho fits best because this construct cannot have any other meaning (compared to while). But some other people prefer while(1) for the "same" reason...



回答4:

while(1) and for(;;) are exactly equivalent and both are well-understood idioms to code infinite loops.

I would avoid the use of goto: to break from an infinite loop or to proceed to the next iteration, use break and continue.



回答5:

None. Use what is the most readable to you



回答6:

In C, true is implemented as follows (depending on compiler)

#define TRUE 1

or

#define TRUE (-1)

AND false is implemented as

#define FALSE 0

so while (1) is equivalent to while (true) since 0 is considered false.

the while (1) == for (; ;) as there are no stopping condition.

which is translated to assembler as

:loop
  ...
  ...
  ...
  goto loop

so if the assembler code doesn't have a ret or exit instruction, it's considered a infinite loop.



回答7:

Although there's no significant difference as mentioned in the other posts, a common reason to use for (;;) instead of while (1) is that static analysis tools (and some compilers with certain warning levels) often complain about the while loop.

Goto is a bit nasty, but should produce the same code as the others. Personally, I stick to for (;;) (to keep Lint happy), but I have no problem with while (1).



回答8:

From what I recall of my "disassembling years", it won't make much a difference (compilers are smart enough). It is more about aesthetics IMO.