web-dev-qa-db-ja.com

If-elseブロック内の 'if(0)'ブロックの目的は何ですか?

私の質問は、私がこの主題の中で言及している行についてであり、それはプロダクションコードの中の多くの場所で見ることができます。

全体的なコードは次のようになります。

if (0) {
    // Empty braces
} else if (some_fn_call()) {
    // actual code
} else if (some_other_fn_call()) {
    // another actual code
    ...
} else {
    // default case
}

他の枝は私の質問とは無関係です。ここにif (0)を入れることの意味は何だろうか。中括弧は空なので、私はそれがコードのブロックをコメントすることになっているとは思わない。コンパイラに最適化を強制するのか、それとも意図が異なるのか?

私はここでSOとインターネットでこの明白な事例を探そうとしましたが、成功しませんでした。 JavaScriptについても同様の質問がありますが、Cはありません。別の質問があります。 `if`条件にゼロが割り当てられた場合はどうなりますか? しかし、それは 'if(0)'の使用法自体ではなく、変数へのゼロ代入について説明しています。

139
Zzaponka

私はこれを対称性のために使うことがあるので、最初のifを気にせずに私のエディタで他のelse if{を自由に動かすことができます。

意味的に

if (0) {
    // Empty braces
} else 

partは何もしませんし、それを削除するためにオプティマイザに頼ることができます。

89
PSkocik

#ifステートメントがある場合、これは役に立ちます。

   if (0)
   {
       // Empty block
   }
#if TEST1_ENABLED
   else if (test1())
   {
      action1();
   }
#endif
#if TEST2_ENABLED
   else if (test2())
   {
      action2();
   }
#endif

等.

この場合、任意の(そしてすべての)テストを#ifすることができ、コードは正しくコンパイルされます。ほとんどすべてのコンパイラはif (0) {}部分を削除します。単純な自動生成プログラムでは、コーディングが少し簡単なので、このようにコードを生成できます。最初のenabledブロックを個別に考慮する必要はありません。

104
CSM

生成されたコードでも同じようなパターンが使われています。たとえば、SQLでは、ライブラリが次のwhere句を発行するのを見ました。

where 1 = 1

最初の基準であるかどうかを確認するための追加のチェックではなく、すべての追加の基準の前にandを追加できるので、これはおそらく他の基準を追加することをより簡単にします。

44
seth flowers

書かれているように、if (0) {}節は何もコンパイルしません。

このラダーの一番上にある節の機能は、01またはtrueに変更することによって、一時的に他のすべての機能を一時的に無効にする(デバッグまたは比較の目的で)簡単な場所を提供することです。

42

まだ言及されていない1つの可能性:if (0) {行はブレークポイントのための便利な場所を提供するかもしれません。

デバッグは最適化されていないコードに対して行われることが多いため、常に偽のテストが行​​われ、ブレークポイントを設定することができます。本番用にコンパイルされると、コード行は最適化されます。一見役に立たないような行は、リリースビルドに影響を与えずに開発およびテストビルドのための機能を提供します。

上記の他の良い提案もあります。目的が何であるかを本当に知る唯一の方法は、作者を見つけ出して尋ねることです。あなたのソースコード管理システムはそれを助けるかもしれません。 (blame-type機能を探してください。)

15
studog

最適化についてはよくわかりませんが、私の2セントは次のとおりです。

これは、1つの主要な条件が削除された(最初のifブロック内の関数呼び出しなど)というコードの変更が原因で発生しましたが、開発者/メンテナ

そのため、関連するifブロックを削除する代わりに、単に条件をif(0)に変更して先に進みました。

15
Sourav Ghosh

それはコードの腐敗です。

ある時点で "if"が何か役に立つことをしたら、状況は変わりました。おそらく評価されている変数が削除されたのでしょう。

システムを修正/変更していた人は システムのロジックに影響を与えるためにできるだけ少ない 彼はコードが再コンパイルされることを確認しました。それで、彼は "if(0)"を残します。なぜならそれは速くて簡単であり、そしてそれが彼が望んでいることであることを完全に確信していないからです。彼はシステムを動作させることができ、そしてそれを完全に修正するために戻ることはしません。

次の開発者がやってきて、それが意図的に行われたと思います そしてコードのその部分だけをコメントアウトし(それはとにかく評価されないので)、次にコードに触れるとそれらのコメントは削除されます。

14
Dark Matter

テンプレート言語を使用して生成された、事前に拡張されたJavaScript内の到達不可能なコードブロックを見ました。

例えば、あなたが読んでいるコードは、当時はサーバー側でしか利用できない変数に依存していた最初の条件を事前評価したサーバーから貼り付けられた可能性があります。

if ( ${requestIsNotHttps} ){ ... }else if( ...

これは、かつてプリコンパイルしたものです。

if ( 0 ){ ... }else if ( ...

これがあなたが私が熱意を表すプロリサイクルコーダー時代の潜在的な低いキーボード活動を相対化するのを助けることを願っています!

9
simonarame

その構造はCで使用され、型安全性を持つ一般的なプログラミングを実装することもできます。それは、到達不可能なコードがコンパイラによってまだチェックされているという事実に依存しています。

// this is a generic unsafe function, that will call fun(arg) at a later time
void defer(void *fun, void *arg);

// this is a macro that makes it safer, by checking the argument
// matches the function signature
#define DEFER(f, arg) \
   if(0) f(arg); \              // never actually called, but compile-time checked
   else defer(f, (void *)arg);  // do the unsafe call after safety check

void myfunction(int *p);

DEFER(myfunction, 42);     // compile error
int *b;
DEFER(myfunction, b);      // compiles OK
8
philfr

ただ悪いコードだと思います。 Compiler Explorerで簡単な例を書くと、gccとclangの両方で、最適化が完全に無効になっていてもif (0)ブロックに対してコードが生成されないことがわかります。

https://godbolt.org/z/PETIks

if (0)を削除しても、生成コードは変更されませんので、これは最適化ではないと結論します。

上部のifブロックに、後で削除されたものがあった可能性があります。つまり、削除するとまったく同じコードが生成されるように見えるので、自由に実行してください。

6
cha0site

言われているように、ゼロはfalseと評価され、分岐はおそらくコンパイラによって最適化されるでしょう。

私はまた前に、新しい機能が追加されてキルスイッチが必要とされたコードでこれを見ました(もし何か機能に問題があればあなたはただそれをオフにすることができます)。プログラマもブランチを削除しませんでした、例えば.

if (feature_a_active()) {
    use_feature_a();
} else if (some_fn()) {
   ...

なりました

if (0) {
   // empty
} else if (some_fn()) {
   ...
6
sergiopm
    Actually according to my opinion, if we put any variable for checking inside
    e.g:-
public static void main(string args[])
{
        var status;
        var empList=_unitofWork.EmpRepository.Get(con=>con.isRetired==true);
        //some code logic 
        if(empList.count>0)
        {
          status=true;
        }
        if(status)
        {
         //do something
        }
        else
        {
        //do something else
        }
}
     if then its dynamically get the value in run time and invoke the logic inside it, else its simply extra line of code i guess.

    Anybody have any depth knowledge why this thing is used....or agree with me.
    kindly respond. 

Ifブロック1を置くだけで、このブロックをデバッグするのに役立ちます。そしてif elseブロックを拡張することもできます。

1