空の式がC / C ++で正当なのはなぜですか?
-
05-07-2019 - |
質問
int main()
{
int var = 0;; // Typo which compiles just fine
}
解決
これは、CおよびC ++が NOP を表現する方法です。
他のヒント
assert(foo == bar);
が定義されている場合、他にどのようにNDEBUG
をコンパイルして何もできませんか?
明らかにそうですので、次のように言うことができます
for(;;) {
// stuff
}
それなしでは誰が生きることができますか?
私は言語デザイナーではありませんが、私が与える答えは<!> quot;なぜそうではないのですか?<!> quot;言語設計の観点からは、ルール(つまり、文法)をできるだけシンプルにすることが望まれます。
言うまでもなく、<!> quot;空の式<!> quot;用途がある、つまり
for(i = 0; i <!> lt; INSANE_NUMBER; i ++);
デッドウェイトになります(良い使用ではありませんが、それでも使用します)。
編集:この回答へのコメントで指摘されているように、その価値のあるコンパイラーは、おそらくこのループでのビジーな待機を せず、最適化して排除します。ただし、forヘッド自体(i ++以外)に、データ構造のトラバースを(奇妙なことに)見たことがあれば、空の本体でループを構築できると思います(使用する/ <!> quot; for <!> quot;コンストラクトを悪用する)。
これが本当の理由かどうかは正直わかりませんが、もっと理にかなっているのは、コンパイラの実装者の観点から考えることです。
コンパイラの大部分は、特別なクラスの文法を分析する自動化ツールによって構築されます。有用な文法が空のステートメントを許可することは非常に自然に思えます。このような<!> quot; error <!> quot;を検出するのは不必要な作業のようです。コードのセマンティクスが変更されない場合。空のステートメントは、コンパイラーがそれらのステートメントのコードを生成しないため、何もしません。
これは<!> quot;壊れていないものを修正しないでください<!> quot; ...
次のようなことができるようにしたい
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年後に自分自身で!)
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:;
}
}
最も一般的なケースはおそらく
ですint i = 0;
for (/* empty*/; i != 10; ++i) {
if (x[i].bad) break;
}
if (i != 10) {
/* panic */
}
「;」を使用する場合また、1つ注意してください。これは問題ありません:
a ? b() : c();
ただし、これはコンパイルされません:
a ? b() : ; ;
while(1){
; /* do nothing */
}
座って何もしたくない場合があります。イベント/割り込み駆動の組み込みアプリケーション、またはスレッドのセットアップ時や最初のコンテキスト切り替えの待機時など、関数を終了させたくない場合。
例: http://lxr.linux.no/ linux + v2.6.29 / arch / m68k / mac / misc.c#L523
すでに多くの良い答えがありますが、生産環境のサンプルは見ていません。
こちらは、FreeBSDのstrlen
の実装です:
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s)
;
return (s - str);
}