为什么C99编译器没有将"!a && b"优化为"a <b"的布尔值?

ndb*_*ent 3 c boolean-logic boolean compiler-optimization

我看到这个非常有趣的推文:

抵制我的代码高尔夫本能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);
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试用gnu90C99标准编译这个程序.我知道C99有一个bool类型,但仍然被视为整数,所以编译器不能根据布尔逻辑进行任何优化?

我可能正在阅读程序集错误,但它看起来像C99 -O3还包括jneje指令,而不是只使用一个"小于"操作和单个跳转指令.看起来C++也没有进行这种优化.

n. *_* m. 7

编译器非常了解其等价性,并能够根据它进行优化.他们的想法应该优化什么可能与你的相反.

为了完整起见,这里是一个函数的clang生成的汇编输出,!a && b它执行"a <b"的函数.在两种情况下都是相同的装配输出.

    mov     eax, edi
    not     al
    and     al, sil
    ret
Run Code Online (Sandbox Code Playgroud)