I created a minimal C++ program:
int main() {
return 1234;
}
and compiled it with clang++5.0 with optimization disabled (the default -O0
). The resulting assembly code is:
pushq %rbp
movq %rsp, %rbp
movl $1234, %eax # imm = 0x4D2
movl $0, -4(%rbp)
popq %rbp
retq
I understand most of the lines, but I do not understand the "movl $0, -4(%rbp)". It seems the program initializes some local variable to 0. Why?
What compiler-internal detail leads to this store that doesn't correspond to anything in the source?
TL;DR : In unoptimized code your CLANG++ set aside 4 bytes for the return value of
main
and set it to zero as per the C++(including C++11) standards. It generated the code for amain
function that didn't need it. This is a side effect of not being optimized. Often an unoptimized compiler will generate code it may need, then doesn't end up needing it, and nothing is done to clean it up.Because you are compiling with
-O0
there is a very minimum of optimizations done on code (-O0
may remove dead code etc). Trying to understand artifacts in unoptimized code is usually a wasted exercise. The results of unoptimized code are extra loads and stores and other artifacts of raw code generation.In this case
main
is special because in C99/C11 and C++ the standards effectively say that when reaching the outer block ofmain
the default return value is 0. The C11 standard says:The C++11 standard says:
In the version of CLANG++ you are using the unoptimized 64-bit code by default has the return value of 0 placed at
dword ptr [rbp-4]
.The problem is that your test code is a bit too trivial to see how this default return value comes in to play. Here is an example that should be a better demonstration:
This code has two exit explicit exit points via
return 5678
andreturn 42;
but there isn't a finalreturn
at the end of the function. If}
is reached the default is to return 0. If we examine the godbolt output we see this:As one can see the compiler has generated a common exit point that sets the return value (EAX) from the stack address
dword ptr [rbp-4]
. At the beginning of the codedword ptr [rbp-4]
is explicitly set to 0. In the simpler case, the unoptimized code still generates that instruction but goes unused.If you build the code with the option
-ffreestanding
you should see the default return value formain
no longer set to 0. This is because the requirement for a default return value of 0 frommain
applies to a hosted environment and not a freestanding one.