56

我读了一些遗留代码:

if ( 1 || !Foo() )

有什么理由不写:

if ( !Foo() )
4

4 回答 4

134

两者一样。第一个永远不会评估Foo(),因为1短路了||.

为什么这样做 - 可能有人想强制进入then分支以进行调试并将其留在那里。也可能是这是在源代码控制之前编写的,所以他们不希望代码丢失,而只是暂时绕过

于 2013-10-10T09:44:00.423 回答
44

if (1 || !Foo() )将永远满足。!Foo()甚至不会因为短路评估而达到。

当您想确保下面的代码if将被执行时,就会发生这种情况,但您不想删除其中的真实条件,可能是出于调试目的。

可能对您有所帮助的其他信息:

  • if(a && b)- 如果afalseb将不会被检查。
  • if(a && b)- 如果atrue,b将被检查,因为如果是false,则表达式将为false
  • if(a || b)- 如果atrueb则不会被检查,因为true无论如何都是这样。
  • if(a || b)- if ais false,b将被检查,因为 if bis truethen itll be true

强烈建议为此目的使用宏,例如DEBUG_ON 1,这将使程序员更容易理解程序员的意思,并且代码中不要有幻数(感谢@grigeshchauhan)。

于 2013-10-10T09:44:42.653 回答
11
1 || condition

始终为真,无论 是否condition为真。在这种情况下,condition甚至从未被评估过。以下代码:

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

输出5因为c永远不会增加,但是如果您更改10c++将实际调用 ,从而产生输出6


通常的实际用法是在您想要测试在很少满足评估为真的条件时调用的某些代码的情况:

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

这种方式condition永远不会被评估,因此// code I want to test总是被调用。但是,它绝对不同于:

if (condition) { ...

这是一个condition将被实际评估的语句(在你的情况下Foo将被调用)

于 2013-10-10T09:44:27.957 回答
10

问题得到了正确回答 - 不同之处在于 or 操作的右侧被短路,这表明这是强制进入 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 的代码。这段代码不应该这样写,因为它显然没有传达意图。它永远不应该被签入(或被允许签入)(源代码控制?同行评审?)绝对不应该允许它以当前形式在生产中执行。

于 2013-10-10T13:33:44.407 回答