2016-11-18 17 views
2

奇妙なコードに遭遇しました。実用的なアプリケーションがあるのか​​、それとも単調な奇妙なのか疑問に思いました。c/C++そうでない場合にelseを使用する

コードは、基本的に次のようになります。私はそれが任意のベアリングを持っている疑いかかわら

#ifdef PREPROCESSOR_CONDITION 
    if (runtime_condition) { 
    } else 
#endif 
    { 
     //expression 
    } 

私は、マクロビットが含まれています。 runtime_conditionがtrueのときに実行されるコードはありません。elseブロックだけが実行されます。私はこれをif(!runtime_condition)とelseブロック(これはもっと簡単だろう)と全く同じにするべきだと思っていますが、何らかのコンパイラ最適化が起こっているのでしょうか?

または、あなたが知っているのは、削除されたifブロック内に何かがあった可能性があります。常にを条件付き間違いを確保

+0

'if(runtime_condition)'と空のコードブロックでは、誰かが「空白を埋める」のを待っている例です。それは奇妙ではありませんが、よく使用されるテクニックです。 –

+0

このコードは公開されていますか?私たちが文脈を知っていれば、より良い答えを出すことができるかもしれません。時には、すでに複雑なif条件に否定を加えないことは明白です。同僚は空の真の部分に '/ * how nice * /'というコメントを追加して読者に見落としではないことを示していました。 –

+0

何らかのバージョン管理システムにチェックインされている場合は、ファイル履歴をチェックして、空のブロックからコードが削除されたかどうかを確認できます。 gitでは、例えば 'git blame'を使うことができます。 – MrEricSir

答えて

2

"マクロビット"は重要です。

は、プログラマが誤ってこれは関係なく、PREPROCESSOR_CONDITIONが定義されているかどうかの、コンパイルエラーになります

#ifdef PREPROCESSOR_CONDITION 
if (runtime_condition) 
{ 
} 
else 
#endif 
{ 
    //expression 
} 
else 
{ 
    // another expression 
} 

にスニペットを変更した場合に何が起こるかを考えてみましょう。

変更すると、

#ifdef PREPROCESSOR_CONDITION 
if (!runtime_condition) 
#endif 
{ 
    //expression 
} 
else 
{ 
    // another expression 
} 

それはPREPROCESSOR_CONDITIONが定義されている場合、コンパイルが、それが定義されていない場合に失敗します。

elseを追加するプログラマが、PREPROCESSOR_CONDITIONの条件でコンパイルを試みるだけであれば問題は見つかりません。 PREPROCESSOR_CONDITIONが未定義でコードがコンパイルされるまで公開されない潜在的な欠陥がコード内に存在します。

これは、単一のコードスニペットではごくわずかなように見えるかもしれませんが、大きなプロジェクトで発生すると、驚きによって発生するコンパイルエラー(予期しない場所でのコードの破損など)

+0

多くの意味がありますそれはターゲットプラットフォームがたくさんある非常に大きなプロジェクトなので、機能を管理するためにかなり多くのプリプロセッサ条件が使用されています。面白い、私はちょうど同じ事を "私"の方法で行うファイルの後のインスタンスを見つけました。 Yeesh。 – squeevee

+0

そのインスタンスは、そのプロジェクトの一部の貧しい開発者によって発見されるのを待っている潜在的な欠陥の例です。個人的には、バグレポートを提出します。特に、このようなことに対処するコーディングガイドラインがある場合(ガイドライン/ポリシーからの逸脱を引用するだけです)。 – Peter

2

は、(それが条件としてコンパイルされたときに、それらの機会に)二つの枝を持って、常にPREPROCESSOR_CONDITIONが定義されているプラ​​ットフォーム上で動作し、誰かが欠けてひたすら本当elseブロックを追加しないことを保証このブロックがどのように動作するかは明らかではありません(または悪化すると、コードがどこでもコンパイルされますが、元の作者の意図がどんなものであっても、方法)。

これが意図の場合、UNLESSのような名前のマ​​クロの背後にあるif-empty-elseの正確な詳細を隠すことによって、明示的に通信するのが通常は意味があります。


これは間違いなく最適化とは関係ありません。コンパイラは、ブロックをスキップするかどうかを判断するために、述語の値を逆転させる必要があります(つまり、if (A) {B;} C:...は実際にはif (!A) goto C; B; C:...を意味します)。これは、手書きで手書きされた!を最も外側に折り畳むことを意味しますとにかく条件式の構造への表現のレベル。大部分の命令セットはjump-if-truejump-if-not-true命令の両方を提供するので、これを行うことは完全に無料であり、ソースに "if not"を書く両方の方法で同じマシンコード最適化をしなくても非常に簡単なコンパイラですらあります。

関連する問題