使用 if(1 || !Foo()) 有啥理由吗?

Posted

技术标签:

【中文标题】使用 if(1 || !Foo()) 有啥理由吗?【英文标题】:Is there any reason for using if(1 || !Foo())?使用 if(1 || !Foo()) 有什么理由吗? 【发布时间】:2013-10-18 00:13:50 【问题描述】:

我阅读了一些遗留代码:

if ( 1 || !Foo() )

有什么不写的理由吗:

if ( !Foo() )

【问题讨论】:

'1 || something()' 将始终产生 true。所以这两个语句是不等价的,但至于为什么这样做,通过。 if (1 || !foo()) if (1). 这很可能是临时完成的,以强制条件为真(可能是错误、解决方法或重构)而不是放回原处。使用源代码管理的注释/归咎功能查找更改的版本——您可能会获得有用的注释或错误数据库条目,以帮助找出更改的原因 也许 Foo() 被实现为return rand() % 2; 1 && !Foo() 等于 !Foo() 【参考方案1】:

两者相同。第一个永远不会评估Foo(),因为1 会使|| 短路。

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

【讨论】:

听起来像是在开发/调试过程中插入的东西,然后因为有人忘记删除它,或者害怕破坏某些东西而留下。 在任何情况下,这都是比注释掉更好的解决方案,因为编译器会不断检查非活动代码。出于调试原因,我一直这样做。 只有真正有经验的开发人员才知道这一点。 +1【参考方案2】:

if (1 || !Foo() ) 将永远满意。由于short-circuits evaluation,甚至无法联系到!Foo()

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

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

if(a && b) - 如果 afalse,则不会检查 bif(a && b) - 如果atrue,将检查b,因为如果是false,则表达式将为falseif(a || b) - 如果atrue,则不会检查b,因为无论如何这是trueif(a || b) - 如果afalse,则将检查b,因为如果btrue,那么它将是true

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

【讨论】:

所以if(1 || !Foo() ) code == if(1)code == codeif (!Foo()) 可以是code 或只是; 取决于Foo() 返回的值。 :) 我扩展了你最后的表达式.. 编辑:出于调试目的,使用宏 DEGUG_ON = 1 或注释它。 if (DEGUG_ON || !Foo()) (其实我会评论代码)。 ;) “强烈建议为此使用宏,例如 DEBUG_ON 1”... 是的,但代码可读性是您在尝试查找时最不关心的问题该死的错误:-) @Mehrdad 确实如此。但是这个错误检查本身可能会变成一个错误..或者是一个混乱,就像它对 OP 所做的那样:D【参考方案3】:
1 || condition

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

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

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


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

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

这样condition 将永远不会被评估,因此// code I want to test 总是被调用。但是它绝对不一样:

if (condition)  ...

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

【讨论】:

you don't want to wait till that condition will evaluate to true 是的,基本上短路是一种保存执行的技术! @GrijeshChauhan:我不是指性能,也不是执行时间。我指的是满足特定标准。 哎呀,这是一个奇怪的语言功能。我相信如果 conding 有副作用,它总是会被评估(所以基本上我相信非常量方法和静态函数被评估了,但是我在一个简单的“hello world”中尝试过,并且永远无法在第一种情况O_O【参考方案4】:

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

【讨论】:

以上是关于使用 if(1 || !Foo()) 有啥理由吗?的主要内容,如果未能解决你的问题,请参考以下文章

有啥理由不使用“受保护”的属性吗?

有啥理由不使用全局 lambda?

有啥理由不对函数使用 INLINABLE pragma 吗?

有啥理由不放弃“var”吗?

今天有啥理由不使用 <script defer> 吗?

进程终止会自动释放所有使用的内存吗?有啥理由明确地这样做吗?