为了简化问题,只考虑表达式的一部分:val < 0
. 本质上,这意味着“如果val
为负,则返回1
,否则0
”;你也可以这样写:
val < 0 ? 1 : 0
如何将其转换为处理器指令在很大程度上取决于编译器和目标处理器。最简单的方法是编写一个简单的测试函数,如下所示:
int compute(int val) {
return val < 0 ? 1 : 0;
}
并查看编译器生成的汇编代码(例如,使用gcc -S -o - example.c
)。对于我的机器,它无需分支即可完成。但是,如果我将其更改为 return5
而不是1
,则会出现分支指令:
...
cmpl $0, -4(%rbp)
jns .L2
movl $5, %eax
jmp .L3
.L2:
movl $0, %eax
.L3:
...
因此,“在表达式中使用的比较不会生成分支”确实是一个神话。(但“在表达式中使用的比较总是会产生一个分支”也不是真的。)
响应此扩展/说明的补充:
我在问是否有任何(健全的)平台/编译器可能有一个分支。MIPS/ARM/x86(_64)/等。我正在寻找的只是一个证明这是一种现实可能性的案例。
这取决于你认为什么是“健全”的平台。如果古老的6502 CPU 系列是理智的,我认为val > 0
没有分支就无法计算它。另一方面,大多数现代指令集都提供某种类型的 set-on-X 指令。
(val < 0
实际上即使在 6502 上也可以不进行分支计算,因为它可以实现为位移。)