c中的内部短路评估

Posted

技术标签:

【中文标题】c中的内部短路评估【英文标题】:inner short circuit evaluation in c 【发布时间】:2015-12-01 09:25:36 【问题描述】:

我知道 Java 和 C/C++ 有短路评估,即在 if (a && b) 中,如果 a 不正确,b 将永远不会评估。

但是如果我有像if ( (a && b) OP c ) 这样的表达式(其中OP 是任意逻辑运算符),如果a = false 会评估b 吗?谢谢。

【问题讨论】:

你知道,最简单的事情就是测试这个...... @RealSkeptic 我可以测试它,但标准是怎么说的? 没有标准这是布尔逻辑 Java 的标准是the JLS。 @coincoin:只有当标准真的这么说的时候。这个问题是有道理的。 【参考方案1】:

C 标准这么说 -

6.5.13 逻辑与运算符

    && 运算符保证从左到右的评估...... .如果第一个操作数比较等于 0,则不计算第二个操作数。

所以如果a==flase b 不会被评估。

【讨论】:

【参考方案2】:

如果 a = false : a && b == 0 无论b 的值是多少,您将始终拥有。为什么评估后执行的操作会改变这种情况?

a b  |  a && b 
0 0  |   0
0 1  |   0

【讨论】:

这是一个关于 Java 和 C++ 的问题,因此使用布尔值作为整数可能不是解释您的观点的最佳方式。顺便说一句,a = false 应该是 a == false 或者更好的是 !a 最后,短路没有绝对合理的原因,人们可能仍然想通过评估b来触发一些副作用,而不必考虑顺序。相反,a 是假的也可以防止这种副作用发生。这只是一个约定问题,那些语言选择短路作为约定 @Dici 与约定无关。这是根据定义。在 Java 中,a == 5 && remove(42)defined,如果 a 不是 5,则不调用 remove() 方法,而 a == 5 & remove(42)defined,始终调用 remove() 方法. 这是一个约定,因为我可以创建一种总是评估所有表达式的语言......这是语言创造者的选择,而不是义务 @Dici:然后您使用bool-only 子表达式和位操作作为逻辑运算符。这也有效,但可以避免短路。或者你使用 Ada,它提供了两种日志操作。对于大多数应用,短路是更好的选择或无关紧要。注意:在表达式中允许副作用也是一种“约定”【参考方案3】:

如果a=false 则不会检查b 的条件,因此(a && b) 总是错误 并且下一个条件取决于使用的 OP,如果它是 &&,它将不会被评估。如果是||,它将被评估。

所以

((a && b) OP c)

这里如果a=false (a && b) 将永远为假。

【讨论】:

&| 不是逻辑运算符。 &| 是位运算符。 对不起,我指的是 C/C++。 @RealSkeptic 抱歉错误,感谢您告诉我查看文档 & 和 |是位操作符docs.oracle.com/javase/tutorial/java/nutsandbolts/… @Andreas:这是一个很好的例子,说明为什么在一个问题中加入多个语言标签是个坏主意。

以上是关于c中的内部短路评估的主要内容,如果未能解决你的问题,请参考以下文章

关于短路评估的安全问题[重复]

JOIN 子句中的 MySQL 逻辑评估是不是延迟/短路?

在执行相同功能时如何避免 C# 中的短路评估

你能防止 Lua 中的短路评估吗?

C ++编译器优化和短路评估[重复]

短路评估和副作用[重复]