I wrote a simple code on a 64 bit machine
int main() {
printf("%d", 2.443);
}
So, this is how the compiler will behave. It will identify the second argument to be a double hence it will push 8 bytes on the stack or possibly just use registers across calls to access the variables. %d expects a 4 byte integer value, hence it prints some garbage value.
What is interesting is that the value printed changes everytime I execute this program. So what is happening? I expected it to print the same garbage value everytime not different ones everytime.
It’s undefined behaviour, of course, to pass arguments not corresponding to the format, so the language cannot tell us why the output changes. We must look at the implementation, what code it produces, and possibly the operating system too.
My setup is different from yours,
with gcc-4.6.2. But it’s similar enough that it’s reasonable to suspect the same mechanisms.
Looking at the generated assembly (
-O3, out of habit), the relevant part (main) isIf instead of the
double, I pass anint, not much changes, but that significantlyI have looked at the generated code for many variations of types and count of arguments passed to
printf, and consistently, the firstdouble(or promotedfloat) arguments are passed inxmmN,N = 0, 1, 2, and the integer (int,char,long, regardless of signedness) are passed inesi,edx,ecx,r8d,r9dand then the stack.So I venture the guess that
printflooks for the announcedintinesi, and prints whatever happens to be there.Whether the contents of
esiare in any way predictable when nothing is moved there inmain, and what they might signify, I have no idea.