Am I correct in assuming that compiler ‘introspected my string’, or there is another explanation of this?
Yes, this is exactly what happens. It’s a pretty simple and common optimization done by the compiler.
Since your first printf()
call is just:
printf("Hello world\n");
It’s equivalent to:
puts("Hello world");
Since puts()
does not need to scan and parse the string for format specifiers, it’s quite faster than printf()
. The compiler notices that your string ends with a newline and does not contain format specifiers, and therefore automatically converts the call.
This also saves a bit of space, since now only one string "Hello world"
needs to be stored in the resulting binary.
Note that this is not possible in general for calls of the form:
printf(some_var);
If some_var
is not a simple constant string, the compiler cannot know if it ends in \n
.
Other common optimizations are:
strlen("constant string")
might get evaluated at compile time and converted into a number.memmove(location1, location2, sz)
might get transformed intomemcpy()
if the compiler is sure thatlocation1
andlocation2
don’t overlap.memcpy()
of small sizes can be converted in a singlemov
instruction, and even if the size is larger the call can sometimes be inlined to be faster.
Another interesting thing is that in
bar
, compiler zero’ed out the return register (eax
) even though it is avoid
function. Why did it do that there and not infoo
?
See here: Why is %eax zeroed before a call to printf?
Related interesting posts
- Why doesn’t GCC optimize this call to printf?
- Can printf get replaced by puts automatically in a C program?
- Why it shows puts when I disassemble no matter whether I’m using printf or puts?
- Difference between printf@plt and puts@plt
- -O2 optimizes printf(“%s\n”, str) to puts(str)
- How can I get the GCC compiler to not optimize a standard library function call like ‘printf’?