web-dev-qa-db-ja.com

if(1 ||!Foo())を使用する理由はありますか?

私はいくつかのレガシーコードを読みました:

if ( 1 || !Foo() )

書かない理由はありますか?

if ( !Foo() )
56
Elad Benda

2つはnot同じです。 _1_が_||_を短絡するため、最初のものはFoo()を評価しません。

なぜそれが行われるのか-おそらく誰かがデバッグ目的でthenブランチへのエントリを強制し、そこに残したかったのでしょう。これはソース管理の前に書かれた可能性もあるので、コードが失われることを望まず、今のところバイパスされているだけです

134
Luchian Grigore

if (1 || !Foo() )は常に満たされます。 短絡評価 のため、!Foo()にも到達しません。

これは、ifの下のコードが実行されることを確認したいが、realを削除したくない場合に発生します。 )おそらくデバッグ目的で、その中の条件。

あなたを助けるかもしれない追加情報:

  • if(a && b) --afalseの場合、bはチェックされません。
  • if(a && b) --atrueの場合、bがチェックされます。これは、falseの場合、式がfalse
  • if(a || b) --atrueの場合、これはbであるため、trueはチェックされません。
  • if(a || b) --afalseの場合、bがチェックされます。btrueの場合は'はtrueになります。

この目的のためにマクロを用意することを強くお勧めします。たとえば、DEBUG_ON 1、これにより、プログラマーの意味を理解しやすくなり、コードにマジックナンバーが含まれなくなります(@grigeshchauhanに感謝)。

44
Maroun
1 || condition

conditionが真であるかどうかに関係なく、常に真です。この場合、conditionは評価されていません。次のコード:

int c = 5;
if (1 || c++){}
printf("%d", c);

cがインクリメントされることはないため5を出力しますが、10に変更すると、c++が実際に呼び出され、出力は6


これの通常の実際の使用法は、trueと評価される条件がめったに満たされないときに呼び出されるコードの一部をテストする場合です。

if (1 || condition ) {
    // code I want to test
}

この方法では、conditionが評価されることはないため、// code I want to testが常に呼び出されます。しかし、それは間違いなく同じではありません:

if (condition) { ...

これは、conditionが実際に評価される(そして、あなたの場合はFooが呼び出される)ステートメントです。

11
LihO

質問は適切に回答されました。違いは、または操作の右側が短絡していることです。これは、ifブロックへのエントリを強制するデバッグコードであることを示しています。

しかし、ベストプラクティスの利益のために、少なくともベストプラクティスを大まかに突き刺すために、優先度の高い順に代替案を提案します(ベストが最後です)。

注:例をコーディングした後、これはC++の質問であることに気付きました。例は、C#です。うまくいけば、あなたは翻訳することができます。誰かが私を必要としているなら、コメントを投稿してください。

インラインコメント:

if (1 /*condition*/) //temporary debug

アウトオブラインコメント:

//if(condition)
if(true) //temporary debug

名前表示機能

//in some general-use container
bool ForceConditionForDebug(bool forcedResult, string IgnoredResult)
{
      #if DEBUG
          Debug.WriteLine(
              string.Format(
                  "Conditional {0} forced to {1} for debug purposes",
                  IgnoredResult,
                  forcedResult));
          return forcedResult;
      #else
          #if ALLOW_DEBUG_CODE_IN_RELEASE
              return forcedResult;
          #else
              throw new ApplicationException("Debug code detected in release mode");
          #endif
      #endif
}

//Where used
if(ForceConditionForDebug(true, "condition"))...

//Our case
if(ForceConditionForDebug(true, "!Foo()"))...

また、本当に堅牢なソリューションが必要な場合は、リポジトリルールをソース管理に追加して、ForceConditionForDebugを呼び出すチェックインされたコードを拒否できます。このコードは明らかに意図を伝えていないため、そのように記述されるべきではありませんでした。チェックインされるべきではなかった(またはチェックインが許可された)(ソース管理?ピアレビュー?)そして、現在の形式で本番環境で実行することを絶対に許可されるべきではありません。

10
PatrickV