In both C (n1570 7.21.6.1/10) and C++ (by inclusion of the C standard library) it is undefined behavior to provide an argument to printf whose type does not match its conversion specification. A simple example:
printf("%d", 1.9)
The format string specifies an int, while the argument is a floating point type.
This question is inspired by the question of a user who encountered legacy code with an abundance of conversion mismatches which apparently did no harm, cf. undefined behaviour in theory and in practice.
Declaring a mere format mismatch UB seems drastic at first. It is clear that the output can be wrong, depending on things like the exact mismatch, argument types, endianness, possibly stack layout and other issues. This extends, as one commentator there pointed out, also to subsequent (or even previous?) arguments. But that is far from general UB. Personally, I never encountered anything else but the expected wrong output.
To venture a guess, I would exclude alignment issues. What I can imagine is that providing a format string which makes printf expect large data together with small actual arguments possibly lets printf
read beyond the stack, but I lack deeper insight in the var args mechanism and specific printf implementation details to verify that.
I had a quick look at the printf sources, but they are pretty opaque to the casual reader.
Therefore my question: What are the specific dangers of mis-matching conversion specifiers and arguments in printf
which make it UB?
1.9
is always typedouble
. Use1.9f
if you want afloat
. – Recountprintf("%d", 1.9);
What is the "expected wrong output". – Northward%s
is used? The standard doesn't try to do any of that, it just says it's your job to use it correctly. – Recount