最近、無限ループよりも優先するという考えが生まれたと主張するこの記事を見つけました。これは、元々PDP-11で使用可能なCコンパイラが、の追加のマシン命令を生成したためです。for(;;)
while(1)
while(1)
ところで、今ではVisualC++の警告でさえ前者を支持する傾向があります。
for(;;)
そのようなイディオムの帰属はどれほど現実的ですか?
最近、無限ループよりも優先するという考えが生まれたと主張するこの記事を見つけました。これは、元々PDP-11で使用可能なCコンパイラが、の追加のマシン命令を生成したためです。for(;;)
while(1)
while(1)
ところで、今ではVisualC++の警告でさえ前者を支持する傾向があります。
for(;;)
そのようなイディオムの帰属はどれほど現実的ですか?
「for(;;)」イディオムは、元のK&Rで明示的に言及されています。それは私にとって十分な帰属です:)
文脈の欠如のために、しばしば誤ったミスの原因となるため、特定の「賢明な帰属」に注意してください。OPは、メッセージにCとC++の両方のタグを付けました。
現在、K&RはCの歴史については半神である可能性がありますが、C++についての権威とは見なされません。さらに、コンパイラの最適化はC ++で基本的な役割を果たすことができますが、Cシステムプログラマーからは「虐待的」と見なされることがよくあります(Cは「高級言語」ではなく「式付きアセンブラー」と見なされます)。
今日のコンパイラは、まったく同じコードを生成する可能性が高く(これは簡単に証明できます)、どちらを使用するかは好みの問題であり、次に他のコードを使用することです。
そういう意味では、「この本当のことは本当なのに」と読みながら「永遠にfor(;;)
」と読みやすいので、私は好む傾向があります。2ミリ秒の脳が無駄になりました!(しかし、それは個人的な意見です:私はより多くのことを考えなければならない多くの人々を知っています)while(true)
for(;;)
while(true)
しかし、私は両方を「絵画的表現」(実際にテキストを読まずに、写真の記憶を通してどのように見えるかを見るだけ)として認識できます(誰かがあなたを内側から追い出すまでここにとどまります)。
MSの警告については、(のような)不適切に記述された式からあなたを救うことがありますtrue||a
。しかし、内部に操作がない些細な表現では、明らかに悪用されており、表示されるべきではありません。神経質ではありませんが、MSコンパイラはどちらの場合も同じマシンコードを生成します。MSへのフィードバックにより、将来のリリースでの警告について退屈することが少なくなる可能性があります。
V7 Unixコンパイラcc
が生成するものは次のとおりです(SIMHとTUHSのイメージを使用)。
$ cat>a.c
main(){
while(1);
}
$ cat>b.c
main(){
for(;;);
}
$ cc -S a.c
$ cc -S b.c
a.c
(while
)は次のようにコンパイルされます。
.globl _main
.text
_main:
~~main:
jsr r5,csv
jbr L1
L2:L4:tst $1
jeq L5
jbr L4
L5:L3:jmp cret
L1:jbr L2
.globl
.data
b.c
(for
)は次のようになります。
.globl _main
.text
_main:
~~main:
jsr r5,csv
jbr L1
L2:L4:jbr L4
L5:L3:jmp cret
L1:jbr L2
.globl
.data
for(;;)
したがって、最適化を使用しない場合にコンパイルされる命令が少なくなることは、少なくとも真実です。ただし、でコンパイルすると-O
、両方のプログラムでまったく同じアセンブリが生成されます。
.globl _main
.text
_main:
~~main:
jsr r5,csv
L4:jbr L4
.globl
.data
のループ本体を追加しprintf("Hello");
ても、プログラムは同じです。
したがって、このイディオムはPDP-11機械語に端を発している可能性がありますが、1979年までにその違いはすでにほとんど無関係でした。
それが本当かどうかはわかりませんが、記事の主張は賢明で現実的です。そしてfor(;;)
タイプするのはより短いwhile(1)
ええと PDP-11は、独自のPDP-11命令セット用の独自のMACROアセンブラーをすでに備えている「マシン」(言語ではない)であったため、K&RがPDP-11コンパイラーを作成しなかったことがわかると思います。
K&Rは(評判の良い)独自の「C」コンパイラを...まあ..もしマクロである必要があるとしたら(それがPDPで利用可能な唯一の命令セットアセンブラだったので)そして(評判の良い)Unixを書いた「C」では、DECのPDP-11オペレーティングシステム(RT-11およびRSTS-11)よりも優れていると考えていたので..そしておそらく正しかったのです!
for(;;)
慣用句なので、経験豊富なCプログラマーだけがコードを読むことができれば素晴らしいことです。 while(true)
経験の浅いプログラマーや非Cプログラマーにとってより理解しやすいでしょう。前者はまた、いくつかの明白でない動作、つまり空のブール式がtrueと評価されることに依存しています。これらの理由で、あなたが1つを選ばなければならないならば、私は後者のために行くと言うでしょう。
ただし、事実上すべての実際のケースで、プログラマーはコードが永久にループすることを望んでいないと私は主張します。ユーザーがcontrol-Cを押しただけの場合でも、ループを終了したい理由は常にあります。無限ループは必要ありません。