What happens to a float variable when %d is used in a printf?

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.

Leave a Comment