Reputation: 13803
I saw this really interesting tweet:
resisting my code golf instinct to turn
if(!bool1 && bool2)
intoif(bool1<bool2)
I had never seen that before, so I wanted to see if compilers would also use this optimization. I started a repo with a README and a test C program: https://github.com/ndbroadbent/gcc_experiments
Here is the test program:
#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);
}
}
I tried compiling this program with both the gnu90
and C99
standards. I know C99 has a bool
type, but is that still treated like an integer, so the compiler can't make any optimizations based on boolean logic?
I might be reading the assembly wrong, but it looks like C99 with -O3
is also including jne
and je
instructions, instead of just using one "less than" operation and a single jump instruction. It looks like C++ doesn't make this optimization either.
Upvotes: 3
Views: 154
Reputation: 119877
Compilers are well aware of the eqivalence and are able to optimise based on it. Their idea of what should be optimised to what might be opposite from yours though.
For sake of completeness, here's the clang-produced assembly output of a function that does !a && b
and also of a function that does “a < b”. It's the same assembly output in both cases.
mov eax, edi
not al
and al, sil
ret
Upvotes: 7