8

Or in other words: Could a wrong printf / fprintf decimal integer (%d, %u, %ld, %lld) format string cause a program to crash or lead to undefined behavior?

Cosinder following lines of code:

#include <iostream> #include <cstdio> int main() { std::cout << sizeof(int) << std::endl << sizeof(long) << std::endl; long a = 10; long b = 20; std::printf("%d, %d\n", a, b); return 0; } 

Result on 32 bit architecture:

4 4 10, 20 

Result on 64 bit architecture:

4 8 10, 20 

In any case the program prints the expected result. I know, if the long value exceeds the int range, the program prints wrong numbers – which is ugly, but doesn't effect the main purpose of the program –, but beside this, could anything unexpected happen?

1

5 Answers 5

12

What can happen if printf is called with a wrong format string?

Anything can happen. It is Undefined behavior!
Undefined behavior means that anything can happen. It may show you results which you expect or it may not or it may crash. Anything can happen and you can blame no one but yourself about it.

Reference:

c99 Standard: 7.19.6.1:
para 9:

If a conversion specification is invalid, the behavior is undefined.225) If any argument is not the correct type for the corresponding coversion specification, the behavior is undefined.

Sign up to request clarification or add additional context in comments.

3 Comments

do you mean that char c=1;printf("%d",c); is undefined behavior also ?
"you can blame no one but yourself about it" -- finally I have a good response to this; see "Blaming the programmer" at the end of this blog post.
@rondino No because c gets promoted to int before it is passed to printf() See "default argument promotions".
3

It's undefined behaviour - there is nothing in the specification telling the compiler designer (or C library designer) how this should be handled, and thus they are allowed to do anything.

In practice, is one of those where it's entirely up to the interpretation of the numbers, and most likely, you won't ever get anything GOOD from doing this. The really bad ones are when you mix string with integer formatting - strings will print nicely as (strange, perhaps) numbers, but numbers are unlikely to "work" when passed as strings - because a string is a pointer to the address of the first character - and most numbers are not valid pointers in a typical system, so it will crash.

But there is no guarantee of anything. In your 64-bit example, it's clear that the number is "little endian". Try the same thing with 0x100000000, and it will print 0 - because the rest of the number is lost.

Comments

2

Oh yes - printf depends on the format string to determine the size and type of the variable to fetch next. When the format string is wrong it may try to fetch a variable that isn't even there, with all consequences that may have.

Comments

2

Anything can happen if printf is called with a wrong format string . Its undefined behaviour and one should never rely on undefined behaviour.

Comments

-3

Don't use printf

printf is a relic of the C days, and is no longer needed... Use std::cout and I/O manipulators instead.

4 Comments

This is in general a sound advice but it does not answer the Q.
@AlokSave Very true, but I think the OP asked the wrong question.
There are no wrong questions. There are badly formatted questions and correctly formatted ones. Just ignore the C++ tag on the Q and this becomes a perfectly valid Q.
In our embedded code, we use c++ but don't use iostreams, We use snprintf and vsnprintf in conjunction with custom logging functions/methods. So the printf family is still quite relevant and useful. Also note, that the entire standard c library is "relic" of the old C days. It is widely used, maintained and remains useful to large numbers of developers around the world.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.