Why is such strange code generated?
assembly, g++, x86
Solution
I think it has to do with how `bool` is handled differently in C and C++. In your code, the `if(!a)` first converts `a` to a `bool` (that's what the `test eax, eax; sete al` does), and then tests that boolean (in `al`) for true/false.
If you rename as `.c` and compile the same code with `gcc`, it generates the expected code
mov DWORD PTR [rbp-4], 0
mov eax, DWORD PTR [rbp-4]
test eax, eax
jne .L3
mov eax, DWORD PTR [rbp-4]
add eax, 1
mov DWORD PTR [rbp-4], eax
.L3:
In C, it seems that boolean tests of integral variables happens without the intermediate conversion to `bool`. Note that `al` is never involved, so this implies that the value is never "converted" to a one-byte `bool` before testing it for non-zero.
Problem
Consider a piece of C++ code: ``` int main() { volatile int a=0; if(!a) ++a; } ``` I compile it on amd64 system with g++ (Ubuntu 4.8.1-2ubuntu1~12.04) with command `g++ test.cpp -S -o test.S -masm=intel` and get the following code: ``` ... mov eax, DWORD PTR [ebp-4] test eax, eax sete al test al, al je .L2 mov eax, DWORD PTR [ebp-4] ; don't use result of sete add eax, 1 mov DWORD PTR [ebp-4], eax .L2: mov eax, 0 ; also drop result of sete ... ``` This code really surprises me. At first I thought it has something to do with 64-bit mode. But when I tried to compile with `-m32`, this bit remained the same. Why does it check `eax` for being zero and then recheck the result once more after setting `al` to `ZF`? Why doesn't it just do `test eax,eax\n jne .L2`?