实施无限循环时,使用while(1)
vs for(;;)
vs goto
会有区别吗?
谢谢, Chenz
答案 0 :(得分:51)
即使关闭优化器,它们也是等效的。
示例:
#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
答案 1 :(得分:7)
我刚刚比较了gcc的未经优化的汇编程序输出:
# cat while.c
int main() {
while(1) {};
return 0;
}
# cat forloop.c
int main() {
for (;;) { };
return 0;
}
make汇编输出:
# 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%。
答案 2 :(得分:4)
生成的组件几乎没有任何差异。这更像是一个风格问题:
转到 - 只是ooogly:向后跳,没有明确的无限阻挡
虽然(1) - 更好,但需要“虚拟”条件,并且您经常会被编译器(警告级别4)或静态分析工具警告
对于(;;)的可能不是最漂亮的,但imho非常适合,因为此构造不具有任何其他含义(与while相比)。但是其他一些人更喜欢(1)因为“相同”的原因......
答案 3 :(得分:4)
while(1)
和for(;;)
完全等效,两者都是用于编码无限循环的易于理解的习惯用法。
我会避免使用goto
:打破无限循环或继续下一次迭代,使用break
和continue
。
答案 4 :(得分:3)
无。使用最易读的内容
答案 5 :(得分:3)
虽然其他帖子中没有显着差异,但使用for (;;)
代替while (1)
的常见原因是静态分析工具(以及某些具有某些警告级别的编译器)经常抱怨while loop。
Goto有点讨厌,但应该生成与其他代码相同的代码。就个人而言,我坚持for (;;)
(让Lint高兴),但while (1)
没问题。
答案 6 :(得分:2)
在C中,true
实现如下(取决于编译器)
#define TRUE 1
或
#define TRUE (-1)
AND false实现为
#define FALSE 0
所以while (1)
相当于while (true)
,因为0被认为是假的。
while (1) == for (; ;)
因为没有停止条件。
将其翻译为汇编程序
:loop
...
...
...
goto loop
因此,如果汇编程序代码没有ret
或exit
指令,则认为它是无限循环。
答案 7 :(得分:0)
从我记得的“拆解年代”来看,它不会产生太大的影响(编译器智能就足够了)。它更多的是关于美学IMO。