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

Why doesn't the C99 compiler optimize "!a && b" as "a < b" for booleans?

我看到了this really interesting tweet:

resisting my code golf instinct to turn if(!bool1 && bool2) into 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 指令,而不是只使用一个 "less than"操作和一个单一的跳转指令。看起来 C++ 也没有进行此优化。

编译器很清楚等价性并且能够基于它进行优化。不过,他们关于应该优化什么的想法可能是 opposite from yours

为了完整起见,这里是执行 !a && b 的函数和执行“a < b”的函数的 clang 生成的汇编输出。两种情况下的汇编输出相同。

    mov     eax, edi
    not     al
    and     al, sil
    ret