When you called:
printf("A: %3d B: %6.2f\n", f, f + 0.15);
C automatically converts the float
values to double
(it is a standard conversion made when you call a function that takes variable arguments, such as int printf(const char *fmt, ...);
). For sake of argument, we will assume that sizeof(int)
is 4 and sizeof(double)
is 8 (there are exceptions, but they are few and far between).
The call, therefore, has pushed a pointer onto the stack, plus an 8-byte double for f
, and another 8-byte double for f + 0.15
. When it is processing the format string, the %d
tells printf()
that you pushed a 4-byte int
onto the stack after the format string. Since that is not what you did, you have invoked undefined behaviour; whatever happens next is OK according to the C standard.
However, the most likely implementation blithely reads 4 bytes and prints them as if they were an int
(it trusts you to tell it the truth). Then it comes across the %6.2f
format; it will read 8-bytes off the stack as a double
. There’s an outside chance that this would cause a memory fault for misaligned access (it would require a 64-bit machine with a requirement that double
be aligned on an 8-byte boundary, such as a SPARC), or it will read 4 bytes from f
and 4 bytes from f + 0.15
, putting them together to create some rather unexpected double
value — as your example shows.