2010-02-18 11 views
20

Al implementar un bucle infinito, es que hay una diferencia en el uso de while(1)for(;;) vs vs goto?Al implementar un ciclo infinito, ¿hay alguna diferencia en el uso mientras (1) vs para (;;) vs goto (en C)?

Gracias, Chenz

+1

Siempre uso mientras. No veo sentido en un bucle construido de esa manera. Eso es solo una preferencia personal. (Me parece que falta información, mientras que el ciclo while parece (para mí) más estético) – Tim

+0

técnicamente, el 1 en el tiempo es una condición que debe probarse en cada iteración. Creo que todos los compiladores comunes son lo suficientemente inteligentes como para saltar de uno que, en lugar de uno condicional. Aparte de eso, todos son equivalentes a excepción del estilo. – falstro

+3

¿Qué ciclo infinito es más rápido que el otro? – Anonym

Respuesta

44

son equivalentes, aunque se encienda el optimizador fuera.

Ejemplo:

#include <stdio.h> 

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

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

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

compilar con gcc -O0 da montaje equivalente para todas las 3 funciones:

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 
+8

+1 para código ARM :-) –

+0

¿Qué comando se utilizó para producir este resultado de ensamblaje específico del archivo objeto? – bzeaman

0

De lo que recuerdo de mis años "desmontaje", no hará mucha diferencia (compiladores son inteligentes suficiente). Es más acerca de la estética IMO.

2

En C, true se implementa de la siguiente manera (en función de compilador)

#define TRUE 1 

o

#define TRUE (-1) 

y falsos se implementa como

#define FALSE 0 

así while (1) es equivalente a while (true) ya que 0 se considera falso.

la while (1) == for (; ;) ya que no hay criterio de parada.

que se traduce a ensamblador como

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

por lo que si el código ensamblador no tiene una instrucción ret o exit, se considera un bucle infinito.

6

acabo comparó la salida ensamblador no optimizado de gcc:

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

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

Hacer ensamblador salida:

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

comparar los archivos de ensamblador:

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

Como se puede ver que no hay diferencias significativas. Aquí está la salida

# 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 

Si bien esto no es una prueba técnica que son lo mismo, yo diría que está en el 99,9% de los casos.

3

Ninguno. Usar lo que es la más legible a que

4

Casi no hay diferencia en ensamblador.Es más bien una cuestión estilística:

Goto - sólo ooogly: saltos hacia atrás, no hay un bloque infinito explícita

while (1) - mejor, requiere "ficticia" condición sin embargo y usted será menudo advertido por el compilador (nivel de advertencia 4) o herramienta de análisis estático

para (;;) podría no ser el más bonito, pero encaja en mi humilde opinión el mejor porque esta construcción no puede tener ningún otro significado (en comparación con el tiempo). Pero algunas otras personas prefieren mientras (1) por la "misma" razón ...

2

Aunque no hay una diferencia significativa como se menciona en las otras publicaciones, una razón común para usar for (;;) en lugar de while (1) es que las herramientas de análisis estáticas (y algunos compiladores con ciertos niveles de advertencia) a menudo se quejan del ciclo while.

Goto es un poco desagradable, pero debe producir el mismo código que los demás. Personalmente, me atengo al for (;;) (para mantener feliz a Lint), pero no tengo ningún problema con while (1).

3

while(1) y for(;;) son exactamente equivalentes y ambos son expresiones idiomáticas bien entendidas para codificar bucles infinitos.

Evitaría el uso de goto: para salir de un ciclo infinito o para pasar a la siguiente iteración, use break y continue.

Cuestiones relacionadas