int main()
{
int var = 0;; // Typo which compiles just fine
}
11 に答える
が定義されている場合、他にどのようにassert(foo == bar);
して何もコンパイルできませんか?NDEBUG
これは、CおよびC++がNOPを表現する方法です。
あなたは次のようなことができるようになりたい
while (fnorble(the_smurf) == FAILED)
;
ではなく
while (fnorble(the_smurf) == FAILED)
do_nothing_just_because_you_have_to_write_something_here();
だが!次のように、同じ行に空のステートメントを記述しないでください。
while (fnorble(the_smurf) == FAILED);
セミコロンを見逃しやすいので、これは読者を混乱させる非常に良い方法です。したがって、次の行はループの本体であると考えてください。覚えておいてください:プログラミングは本当にコミュニケーションに関するものです—コンパイラーとではなく、あなたのコードを読む他の人々とのコミュニケーションです。(または、3年後に自分で!)
私は言語デザイナーではありませんが、答えは「どうしてですか?」です。言語設計の観点からは、ルール(つまり文法)をできるだけ単純にする必要があります。
「空の表現」には用途があることは言うまでもありません。
for(i = 0; i <INSANE_NUMBER; i ++);
デッドウェイトになります(良い使用法ではありませんが、それでも使用法です)。
編集:この回答へのコメントで指摘されているように、その塩に値するコンパイラは、おそらくこのループで待機し、最適化するのに忙しくないでしょう。ただし、データ構造トラバーサルで(奇妙なことに)行ったfor head自体(i ++以外)にもっと便利なものがある場合は、(/を使用して)空の本体でループを構築できると思います。 「for」構造を悪用する)。
OK、これを実際に使用する可能性のある最悪のシナリオに追加します。
for (int yy = 0; yy < nHeight; ++yy) {
for (int xx = 0; xx < nWidth; ++xx) {
for (int vv = yy - 3; vv <= yy + 3; ++vv) {
for (int uu = xx - 3; uu <= xx + 3; ++uu) {
if (test(uu, vv)) {
goto Next;
}
}
}
Next:;
}
}
正直なところ、これが本当の理由かどうかはわかりませんが、コンパイラの実装者の立場から考える方が理にかなっていると思います。
コンパイラの大部分は、特別なクラスの文法を分析する自動化ツールによって構築されています。有用な文法が空のステートメントを可能にするのは非常に自然なことのようです。コードのセマンティクスを変更しない場合に、このような「エラー」を検出するのは不必要な作業のようです。コンパイラはこれらのステートメントのコードを生成しないため、空のステートメントは何もしません。
これは「壊れていないものを直さないで」の結果に過ぎないように思えます...
明らかに、それは私たちが次のようなことを言うことができるようにするためです
for (;;) {
// stuff
}
それなしで誰が生きることができますか?
最も一般的なケースはおそらく
int i = 0;
for (/* empty */; i != 10; ++i) {
if (x[i].bad) break;
}
if (i != 10) {
/* panic */
}
while (1) {
; /* do nothing */
}
座って何もしたくない時があります。イベント/割り込み駆動型の組み込みアプリケーション、またはスレッドのセットアップや最初のコンテキストスイッチの待機など、関数を終了させたくない場合。
例: http: //lxr.linux.no/linux+v2.6.29/arch/m68k/mac/misc.c#L523