今天我开始研究检查两个 bool 值的分支。我很确定在某些优化级别上,它们只会被添加然后检查,但 gcc 和 clang 不是这种情况。为什么 gcc 不通过用加法和一个检查替换它们来优化两个 bool 检查?让我向您展示示例:
void test(bool a, bool b)
{
// Branch 1
if (a && b)
{
std::cout << "Branch 1";
}
// Branch 2
if (static_cast<int>(a) + static_cast<int>(b))
{
std::cout << "Branch 2";
}
}
gcc(即使具有最大优化级别)为分支 1 生成以下代码:
test dil,dil
je 400794 <test(bool, bool)+0x14>
test sil,sil
jne 4007b0 <test(bool, bool)+0x30>
同时为分支 2 生成以下代码:
movzx ebx,bl
movzx ebp,bpl
add ebx,ebp
jne 4007cf <test(bool, bool)+0x4f>
两个分支(test + je)不应该比加法和分支(add + jne)慢吗?
编辑:我真正的意思是乘法,因为在真假 (1 + 0) 的情况下,加法给出真 (1),但乘法给出正确的结果 (0)。
最佳答案
在抽象机级别,&&
强制在第一个表达式为假时不对第二个表达式求值。根据 as-if 规则,编译器可以选择评估第二个表达式——如果它可以证明它具有已定义的行为(或者未定义的行为无关紧要)并且没有副作用;然而,编译器作者已经明确地决定这是不值得的。
如果您不想走捷径,&
会有所帮助(带有注释)。
关于c++ - 为什么 if 检查没有被优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41508563/