36

在实现无限循环时,使用while(1)vs for(;;)vs有区别goto吗?

谢谢,陈兹

4

8 回答 8

59

即使您关闭优化器,它们也是等效的。

例子:

#include <stdio.h>

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

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

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

编译gcc -O0为所有 3 个函数提供等效程序集:

 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
于 2010-02-18T13:32:55.513 回答
8

我只是比较了 gcc 的未优化汇编输出:

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

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

制作汇编器输出:

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

比较汇编文件:

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

如您所见,没有显着差异。这是输出

# 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

虽然这不是它们相同的技术证据,但我会说它在 99.9% 的情况下是相同的。

于 2010-02-18T13:34:31.887 回答
5

生成的程序集几乎没有任何区别。这更像是一个风格问题:

Goto - 只是ooogly:向后跳转,没有明确的无限块

while(1) - 更好,虽然需要“虚拟”条件,但编译器(警告级别 4)或静态分析工具会经常警告您

for(;;)可能不是最漂亮的,但恕我直言最适合,因为这个结构不能有任何其他含义(与 while 相比)。但是出于“相同”的原因,其他一些人更喜欢 while(1) ......

于 2010-02-18T13:36:16.783 回答
4

尽管与其他帖子中提到的没有显着差异,但使用for (;;)not 的一个常见原因while (1)是静态分析工具(以及某些具有某些警告级别的编译器)经常抱怨 while 循环。

Goto 有点讨厌,但应该产生与其他代码相同的代码。就个人而言,我坚持for (;;)(让 Lint 开心),但我对while (1).

于 2010-02-18T13:38:18.870 回答
4

while(1)并且for(;;)是完全等价的,并且两者都是用于编码无限循环的易于理解的习语。

我会避免使用goto: 来打破无限循环或继续下一次迭代,使用breakand continue

于 2010-02-18T13:44:02.633 回答
3

没有任何。使用对您来说最易读的内容

于 2010-02-18T13:34:46.530 回答
2

在 C 中,true实现如下(取决于编译器)

#define TRUE 1

或者

#define TRUE (-1)

AND false 实现为

#define FALSE 0

sowhile (1)等价于while (true)因为 0 被认为是假的。

因为while (1) == for (; ;)没有停止条件。

被翻译成汇编程序为

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

所以如果汇编代码没有retorexit指令,它被认为是一个无限循环。

于 2010-02-18T13:31:22.357 回答
0

根据我对“反汇编年”的回忆,它不会有太大的不同(编译器足够聪明)。它更多的是关于美学IMO。

于 2010-02-18T13:31:00.430 回答