mar*_*cgg 39 language-agnostic conditional short-circuiting
为什么语言不能使用短路评估?不使用它有什么好处吗?
我看到它可能导致一些表演问题......这是真的吗?为什么?
相关问题:使用短路评估的好处
RBa*_*ung 40
不使用短路评估的原因:
因为如果你的函数,属性获取或操作符方法有副作用,它会表现不同并产生不同的结果.这可能与以下内容相冲突:A)语言标准,B)您的语言的先前版本,或C)典型用户的语言的默认假设.这些是VB不短路的原因.
因为您可能希望编译器可以自由地重新排序和修剪表达式,运算符和子表达式,而不是按照用户键入它们的顺序.这些是SQL不会短路的原因(或者至少不是大多数开发人员认为它会这样做的方式).因此,SQL(和其他一些语言)可能会短路,但只有当它决定并且不一定按照您隐式指定的顺序时.
我假设您在询问"自动,隐式特定于订单的短路",这是大多数开发人员对C,C++,C#,Java等的期望.BB和SQL都有办法明确强制特定于订单短路.然而,通常当人们提出这个问题时,这是一个"做我想要的"问题; 也就是说,它们的意思是"为什么它不能做我想要的?",就像在我写的顺序中自动短路一样.
我能想到的一个好处是,某些操作可能会产生您可能会发生的副作用.
例:
if (true || someBooleanFunctionWithSideEffect()) {
...
}
Run Code Online (Sandbox Code Playgroud)
但这通常不赞成.
Ada默认不这样做.为了强制进行短路评估,您必须使用and then或or else代替and或or.
问题在于,在某些情况下,它实际上会减慢速度.如果第二个条件快速计算,并且第一个条件对于"和"几乎总是为真,或者对于"或"则为假,那么额外的检查分支指令就是一种浪费.但是,据我所知,对于具有分支预测器的现代处理器,情况并非如此.另一个问题是,编译器可能碰巧知道第二一半是便宜还是可能失败,并且可能要相应地重新排序检查(这要是短路行为定义它不能做的).
我听到过反对意见,在第二次测试有副作用的情况下,它会导致代码的意外行为.恕我直言,如果你不太了解你的语言,它只是"意外",但有些人会争辩这一点.
如果您对实际语言设计者对此问题的看法感兴趣,请参阅Ada 83(原始语言)基本原理的摘录:
可以按任何顺序计算布尔表达式(如A和B)的操作数.根据术语B的复杂性,仅当术语A具有值TRUE时,才可能更有效(在一些但不是所有机器上)来评估B. 然而,这是编译器采取的优化决策,并且假设始终完成此优化是不正确的.在其他情况下,我们可能希望表达条件的组合,其中只有在满足先前条件时才应评估每个条件(具有意义).这两件事都可以通过短路控制形式来完成......
在Algol 60中,只能通过使用条件表达式来实现短路评估的效果,否则将执行完整的评估.这通常会导致构造变得乏味,无法遵循......
有几种语言没有定义如何评估布尔条件.因此,基于短路评估的程序将不可移植.这清楚地说明了将布尔运算符与短路控制形式分开的必要性.