代码之家  ›  专栏  ›  技术社区  ›  ndbroadbent

为什么C99编译器不优化“!“A和B”作为“A<B”表示布尔值?

  •  3
  • ndbroadbent  · 技术社区  · 7 年前

    我看见了 this really interesting tweet :

    抵抗我的代码高尔夫本能转向 if(!bool1 && bool2) 进入之内 if(bool1<bool2)

    我以前从未见过这种情况,所以我想看看编译器是否也会使用这种优化。我用自述文件和测试C程序启动了一个repo: 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);
      }
    }
    

    我试着用 gnu90 C99 标准。我知道C99有一个 bool 类型,但它仍被视为整数,因此编译器无法基于布尔逻辑进行任何优化吗?

    我可能读错了程序集,但它看起来像c99 -O3 也包括 jne je 指令,而不是仅仅使用一个“小于”操作和一个跳转指令。看起来C++也没有做出这种优化。

    1 回复  |  直到 7 年前
        1
  •  7
  •   n. m. could be an AI    7 年前

    编译器很好地了解EqiValence,并能够基于它进行优化。他们的想法是什么应该优化到什么可能是 opposite from yours 不过。

    为了完整性,这里是clang生成的函数的汇编输出 !a && b 以及执行__a<b__的函数。这两种情况下都是相同的程序集输出。

        mov     eax, edi
        not     al
        and     al, sil
        ret