My question is about the behavior after a printf with a missing argument:
printf("%s blah blah %d", int); // integer was given as argument (and not int written)
I already know that if there are insufficient arguments for the format, the behavior is
undefined.
The question is whether it is undefined for the printf outcome or for the whole program?
- A crash can happen when %s tried to read from unauthorized memory address. (it happened to me)
- Can a crash happen [long] after the printf complete? (printed some garbage string and an integer)
Edit:
To clarify I’m not asking about compilation errors or warnings, nor can a program crash when executing this line. The question is can this line make the program crash randomly after this line already executed.
Basically for the whole program. Printf starts taking arguments off the stack and, in this case, takes an
intworth too much. That’s usually something like the return address. So when the printf returns, it returns to whatever random number happens to be next on the stack. The usual result — if you’re lucky — is a segmentation fault.Because it pushes arguments onto the stack, it pops them off, so it tries to get the
intfirst.If you’re not lucky, it finds an addressable chunk of code. That leads to your second case, where the address becomes the address of that hash of random characters. Now it’s going to try to print a string until it find a random NUL character.
Update
As Joachim points out, the specifics of this are determined by the calling convention, so let’s make an explicit example. When the printf function is to be called, either the return address is pushed first or its pushed last. We assume it’s pushed first (more common on the usual architecture), so this call is going to need PUSH return-address, PUSH address of the format string, PUSH an int value — let’s say 42. That gives us this stack:
and leaves the stack pointer SP pointing to the next location on the stack.
Now the printf starts to interpret the string. It looks for the address of the
intparameter, and figures out it’s SP-1. So the address of the string parameter must be SP-2 … but that’s the address of the format string, since there is no string parameter. Then when it looks for the address of the format string, it wants to find SP-3, but that’s the return address, an address of executable code. That should, on most any machine, cause a segmentation fault.If you go through the other options for calling convention, you’ll find every one of them looks at some wrong thing, because no matter what, printf thinks it needs to refer to three things off the stack, not the two it has.