36

while(1)無限ループを実装する場合、 vsfor(;;)と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と比較して)他の意味を持つことができないため、imhoが最適です。しかし、「同じ」理由でwhile(1)を好む人もいます...

于 2010-02-18T13:36:16.783 に答える
4

他の投稿で述べられているように大きな違いはありませんが、for (;;)代わりに使用する一般的な理由while (1)は、静的分析ツール(および特定の警告レベルを持つ一部のコンパイラ)がwhileループについて不平を言うことが多いことです。

Gotoは少し厄介ですが、他のコードと同じコードを生成するはずです。個人的にはfor (;;)(リントを幸せに保つために)固執していますが、問題はありませんwhile (1)

于 2010-02-18T13:38:18.870 に答える
4

while(1)for(;;)はまったく同等であり、どちらも無限ループをコーディングするためのよく理解されているイディオムです。

goto無限ループから抜け出すため、または次の反復に進むために:の使用を避け、 andを使用breakcontinueます。

于 2010-02-18T13:44:02.633 に答える
3

なし。あなたにとって最も読みやすいものを使用してください

于 2010-02-18T13:34:46.530 に答える
2

Cでは、true次のように実装されます(コンパイラによって異なります)

#define TRUE 1

また

#define TRUE (-1)

ANDfalseは次のように実装されます

#define FALSE 0

0はfalseと見なされるため、while (1)と同等です。while (true)

停止条件がwhile (1) == for (; ;)ないため。

これはアセンブラに次のように変換されます

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

retしたがって、アセンブラコードにまたは命令がない場合はexit、無限ループと見なされます。

于 2010-02-18T13:31:22.357 に答える
0

私の「逆アセンブルの年」を思い出すと、それほど大きな違いはありません(コンパイラーは十分に賢いです)。それは美学IMOについてです。

于 2010-02-18T13:31:00.430 に答える