为什么位运算符 & 没有短路?

8
我们都知道逻辑运算符&&如果左操作数为false,则会短路,因为我们知道如果一个操作数是false,那么结果也是false
为什么按位运算符&没有短路呢?如果左操作数为0,那么我们知道结果也是0。我测试过的每种语言(C、Javascript、C#)都会在第一个操作数之后继续评估两个操作数。
&运算符短路有什么坏处吗?如果没有,为什么大多数语言不让它短路呢?这似乎是一个显而易见的优化。

1
一个原因是为了允许函数调用的副作用。 - Willem van Rumpt
3
由于位运算符通常用于对整数操作的位运算(并且通常对应于单个机器指令),因此引入附加条件来检查罕见的0情况将不会起到优化作用。为什么乘法不在0时短路?因为它是一种简单的算术运算,对应于单个机器指令,并且没有人会检查每个乘法运算是否有0操作数。 - Christian Rau
如果左操作数为0xFFFFFFFF,位运算符|可能会进行短路。 - Peter Olson
5个回答

11

我猜这是因为源语言中的按位 and 通常会被直接转换为处理器执行的按位 and 指令。这反过来又是通过硬件中适当数量的 and 门实现的。

在大多数情况下,我不认为这会对任何优化产生太大影响。评估第二个操作数通常代价更低,而不是测试是否应该对其进行评估。


1
如果第二个操作数涉及到昂贵的计算,那将会有所裨益。 - Peter Olson
3
是的,只有当左操作数为0的情况非常罕见时才会发生这种情况。请记住,我们在这里讨论的是整数,整数值为0比布尔值“false”更为罕见(即使可能比其他数字更频繁出现)。 - Christian Rau

8

短路并不是优化设备,而是控制流设备。如果您未能短路 p != NULL && *p != 0,您将获得一个崩溃的程序,而不是稍微慢一点的程序。

这种类型的短路运算符对于按位运算符几乎没有意义,and 比普通的非短路运算符更昂贵。


2
这个参数对我来说似乎是反过来的。短路可以被用作流程控制设备,因为它存在于优化中。如果 && 不进行短路,像这样的代码将永远不会被编写;它必须是两个单独的测试。然而,我同意位短路在实践中可能非常罕见,长期来看可能更昂贵。这完全取决于调用代码上下文中左操作数为 0 的可能性。 - Quinn Taylor
@QuinnTaylor 优化,根据定义只影响性能而不影响意义。这样的代码之所以被编写是因为自然而然地编写代码,并且其他替代方案很棘手。如果 && 不进行短路计算,那么该语言可能会逐渐消失并被不那么棘手的语言取代。 - n. m.

2

位运算通常非常快,如果进行检查会使操作时间增加一倍或更多,而短路逻辑运算符的收益潜力非常大。


2

如果编译器必须对&的两个操作数进行检查,我猜在任何正常情况下它都会慢得多。


2

如果第一个操作数是0,*不会短路,原因相同--这将是一个晦涩的特例,并且为此添加特殊运行时测试将使所有乘法变慢。

当操作数不是常量时,短路比不短路更昂贵,因此除非程序员明确要求,否则不要进行短路。因此,您真正想要有清晰简单的规则来确定何时发生短路。


这一点一点都不明显。64位英特尔硬件指令可能在内部实现对零的检查。这就是为什么你不进行检查。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接