Question

so as printf() is a function and it returns the number of characters written if successful or negative value if an error occurred, looking at this example, the output as expected is zero.

#include <stdio.h>    
int main(void) 
{     
printf("%d");    
return 0;
}

now when I add some more of these %d : http://ideone.com/brw5vG the output changes to this: 0 134513819 -1216430092 134513808

I am not able to figure out whats up with the random garbage values? There is a negative value here in the output as well, and a negative value justifies an error, so can anyone pinpoint what is the error here exactly? Please be concise and specific. Thanks.

Was it helpful?

Solution 3

You are mis-specifiying the format string to printf this is undefined behavior and you should have no expectations as to the result. By specifying %d you are telling printf to expect an int argument which you have not provided.

If we look at the C99 draft standard section 7.19.6.1 The fprintf function which also covers pritnf with respect to format specifiers says:

[...]If there are insufficient arguments for the format, the behavior is undefined.[...]

OTHER TIPS

Because "%d" means an integer is expected. You don't pass any, so you get undefined behaviour.

Note that g++ 4.8.2 gives a useful warning:

warning: format '%d' expects a matching 'int' argument [-Wformat=]

similarly for clang++ 3.4:

warning: more '%' conversions than data arguments [-Wformat]

the output as expected is zero

printf("%d");

You should not expect anything as your program invokes undefined behavior.

(C99, 7.19.6.1p2) "[...] If there are insufficient arguments for the format, the behavior is undefined.[...]"

The problem is in how you pose the question; you assume it "should be 0." The fact is that this is undefined behavior, and printf will substitute for %d whatever happens to be in the stack.

Your code invokes undefined behavior. Anything could be happen.

The C11 Standard says in section 7.21.6 Formatted input/output functions:

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

You are passing no argument for the corresponding %d specifier.

There are 2 issues at hand: First is why doesn't the compiler issue an error about this bad call to printf(), and second is why you get garbage output. I'll answer them one at a time.

printf() is a tricky function. While most functions have a constant amount of arguments passed to them, printf() is different. For example, if we take this simple function:

int max(int a, int b) {
  if (a > b) return a;
  else return b;
}

You can see that this function always receives 2 arguments. This is also something that the compiler knows, and enforces when you compile you code. This is why a call such as max(4) won't work. The compiler will see that we are passing max() 1 argument instead of 2 and it will issue an error.

printf() is a function that takes a variable amount of arguments, and this amount is determined by the amount of format specifiers (things that start with %) in the format string. This means that the compiler cannot know at compile time if the amount of arguments that you passed to printf is enough (or maybe too much).

The reason that you get garbage printed is because of how functions read their input arguments. All input arguments for a function reside on the stack. These are pushed into the stack before the function is called and later addressed by the function. In this case, printf() expects to have an extra argument besides the format string (because of the %d), and so it looks in the address where its 2nd argument might have been. Alas, that argument wasn't passed, so it will actually look into a place in the stack that might contain anything else (a return address, a frame pointer, a local variable of an enclosing scope or other).

You can read more about how function calls work here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top