Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

Thanks, Chenz

like image 888
Crazy Chenz Avatar asked Feb 18 '10 13:02

Crazy Chenz


People also ask

Which loop is better for or while?

Use a for loop when you know the loop should execute n times. Use a while loop for reading a file into a variable. Use a while loop when asking for user input. Use a while loop when the increment value is nonstandard.

Can while loops be infinite?

Yes. Following do-while loop is a valid statement and causes an infinite loop.

What is the difference between a finite and infinite loop?

A finite loop ends itself. An infinite loop will not end without an outside cause.

Is while 1 the same as while true?

Why does while distinguish the two? It's emitting a LOAD_GLOBAL (True) for each True , and there's nothing the optimizer can do with a global. So, while distinguishes 1 and True for the exact same reason that + does.


2 Answers

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 
like image 108
kennytm Avatar answered Sep 28 '22 04:09

kennytm


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.

like image 38
Otto Allmendinger Avatar answered Sep 28 '22 04:09

Otto Allmendinger