printf() with no arguments in C compiles fine. how?

I tried the below c program & I expected to get compile time error, but why compiler isn't giving any error?

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

Why output is compiler dependent? Here is the output on various compilers

Output on Orwell Dev C++ IDE (uses gcc 4.8.1) : 0

Output on Visual C++ provided by Visual Studio 2010 : 0

CodeBlocks IDE (uses gcc 4.7.1) : garbage value

Online compiler ideone.com : garbage value

What is going wrong here ?


Your program will compile fine, as printf() is a variadic function and the matching check of the number of format specifiers with supplied argument is not performed by default.

At runtime, your program exhibits undefined behaviour, as there in no argument supplied which has to be printed using the supplied format specifier.

As per chapter 7.19.6.1, c99 standard, (from fprintf())

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

If you compile using -Wformat flag in gcc, your compiler will produce the warning for the mismatch.


Because of how C variadic arguments work, the compiler cannot track their correct usage. It is still (syntactically) legal to provide less, or more, parameters that the function needs to work, although this generally ends up as undefined behavior when looking at the standard.

The declaration of printf looks like this:

int printf(const char*, ...);

The compiler only sees ..., and knows that there may be zero or more additional arguments that the function may or may not use. The called function does not know how many arguments it is passed; it can, at best, assume that it was passed all the information it needs and nothing more.

Contrast this with other languages, like C#:

void WriteLine(string format, params object[] arguments);

Here, the method knows exactly how many additional arguments is was passed (doing arguments.Length).

In C, variadic functions and especially printf are a frequent cause of security vulnerabilities. Printf ends up reading raw bytes from the stack, which may leak important details about your application and its security environment.

For this reason, Clang and GCC support a special extension to validate printf formats. If you use an invalid format string, you'll get a warning (not an error).

code.c:4:11: warning: more '%' conversions than data arguments [-Wformat]
    printf("%d\n");
           ~~^

This is simply undefined behavior if you do not provide the sufficient arguments to printf, which mean the behavior is unpredictable. From the draft C99 standard section 7.19.6.1 The fprintf function which also covers printf for this case:

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

Since printf is a variadic function there is no matching of arguments to the function declaration. So the compiler needs to support support format string checking which is covered by -Wformat flag in gcc:

Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified, and that the conversions specified in the format string make sense. This includes standard functions, and others specified by format attributes (see Function Attributes), [...]

Enabling sufficient compiler warnings is important, for this code gcc using the -Wall flag tells us (see it live):

 warning: format '%d' expects a matching 'int' argument [-Wformat=]
 printf("%d\n");
 ^

This compiles well. Because it matches the printf() prototype which is

printf(const char *,...);

During run-time the call

printf("%d\n");

Tries to fetch the value from second argument and since you have not passed anything it might get some garbage value and print it out so the behavior is undefined here.