C99编译器为什么不将布尔值的“!a && b”优化为“ a <b”?

时间:2018-11-21 17:47:31

标签: c boolean compiler-optimization boolean-logic

我看到了this really interesting tweet

  

抵制我的代码高尔夫本能,将if(!bool1 && bool2)变成if(bool1<bool2)

我以前从未见过,所以我想看看编译器是否也会使用这种优化。我使用自述文件和测试C程序开始了一个仓库:https://github.com/ndbroadbent/gcc_experiments

这是测试程序:

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

int main(int argc, const char* argv[]) {
  if(argc != 3) {
    printf("Usage: %s <a> <b>\n", argv[0]);
    exit(1);
  }
  bool a = strtol(argv[1], NULL, 10) != 0;
  bool b = strtol(argv[2], NULL, 10) != 0;

  if (!a && b) {
    printf("!a && b == true (a: %d, b: %d)\n", a, b);
  } else {
    printf("!a && b == false (a: %d, b: %d)\n", a, b);
  }
}

我尝试使用gnu90C99标准编译该程序。我知道C99具有bool类型,但是仍然像整数一样对待,因此编译器无法基于布尔逻辑进行任何优化吗?

我可能读错了程序集,但是看起来带有-O3的C99还包含jneje指令,而不是仅使用一个“小于”操作和一个单跳指令。看来C ++也没有进行此优化。

1 个答案:

答案 0 :(得分:7)

编译器非常了解等效性,并能够基于等效性进行优化。他们的想法是应该将其优化为opposite from yours

为了完整起见,这是执行!a && b的函数以及执行“ a

    mov     eax, edi
    not     al
    and     al, sil
    ret