Behaviour of printf when printing a %d without supplying variable name

You say that “surprisingly the program compiles”. Actually, it is not surprising at all. C & C++ allow for functions to have variable argument lists. The definition for printf is something like this:

int printf(char*, ...);

The “…” signifies that there are zero or more optional arguments to the function. In fact, one of the main reasons C has optional arguments is to support the printf & scanf family of functions.

C has no special knowledge of the printf function. In your example:

printf("%d");

The compiler doesn’t analyse the format string and determine that an integer argument is missing. This is perfectly legal C code. The fact that you are missing an argument is a semantic issue that only appears at runtime. The printf function will assume that you have supplied the argument and go looking for it on the stack. It will pick up whatever happens to be on there. It just happens that in your special case it is printing the right thing, but this is an exception. In general you will get garbage data. This behaviour will vary from compiler to compiler and will also change depending on what compile options you use; if you switch on compiler optimisation you will likely get different results.

As pointed out in one of the comments to my answer, some compilers have “lint” like capabilities that can actually detect erroneous printf/scanf calls. This involves the compiler parsing the format string and determining the number of extra arguments expected. This is very special compiler behaviour and will not detect errors in the general case. i.e. if you write your own “printf_better” function which has the same signature as printf, the compiler will not detect if any arguments are missing.

Leave a Comment