switch sentencia programacion lenguaje infinitos else ejemplos ciclos c loops for-loop goto while-loop

programacion - sentencia break en c



Al implementar un ciclo infinito, ¿hay alguna diferencia en el uso mientras(1) vs para(;;) vs goto(en C)? (8)

Al implementar un ciclo infinito, ¿hay alguna diferencia en el uso while(1) vs for(;;) vs goto ?

Gracias, Chenz


Acabo de comparar la salida del ensamblador no optimizado de gcc:

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

Hacer salida de ensamblador:

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

Comparar archivos ensambladores:

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

Como puede ver, 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 de que son iguales, diría que es en el 99,9% de los casos.


Apenas hay diferencia en el ensamblaje generado. Es más un problema de estilo:

Goto - simplemente ooogly: salta hacia atrás, sin bloque infinito explícito

while (1) - mejor, requiere una condición "ficticia" y el compilador (nivel de advertencia 4) o la herramienta de análisis estático lo advertirán con frecuencia.

porque (;;) podría no ser el más bonito, pero el imho encaja mejor porque este constructo no puede tener ningún otro significado (en comparación con el tiempo). Pero otras personas prefieren (1) por la "misma" razón ...


Aunque no hay una diferencia significativa como se menciona en las otras publicaciones, una razón común para usar for (;;) 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 debería producir el mismo código que los demás. Personalmente, me atengo a for (;;) (para mantener feliz a Lint), pero no tengo ningún problema con while (1) .


En C, true se implementa de la siguiente manera (según el compilador)

#define TRUE 1

o

#define TRUE (-1)

Y falso se implementa como

#define FALSE 0

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

el while (1) == for (; ;) ya que no hay una condición de parada.

que se traduce al ensamblador como

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

entonces, si el código ensamblador no tiene una instrucción ret o exit , se considera un ciclo infinito.


Ninguna. Usa lo que es más legible para ti


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


Son equivalentes, incluso si apaga el optimizador.

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 proporciona un ensamblaje equivalente para 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


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 .