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 ?
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: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#:
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).This compiles well. Because it matches the printf() prototype which is
During run-time the call
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.
In general diagnostic messages (you may think of them like compilation errors) are not guaranteed for undefined behaviors (like lack of sufficient arguments for
printf
function call as in your case), that are not counted as syntax rule or constraint violations.In other words your compiler is free to translate such unit, but you should never run it or rely on its behaviour (as it's de facto unpredictable). Moreover your compiler is allowed not to provide any documentation (that is C Standard does not enforce it to do so), like it's required for implementation-defined or locale-specific behaviours.
In the context of printf() and fprintf(), as per C standard C11 clause 7.21.6.1, "If there are insufficient arguments for the format, the behavior is undefined. If the format is exhausted while arguments remain, the excess arguments are evaluated (as always) but are otherwise ignored."
You are invoking undefined behaviour. That's your problem, not the compiler's, and basically anything is "allowed" to happen.
Of course, virtually every existing compiler should be able to warn you about this particular condition regarding
printf()
, you just have to allow him to (by enabling, and heeding, compiler warnings).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 section7.19.6.1
The fprintf function which also coversprintf
for this case: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:Enabling sufficient compiler warnings is important, for this code
gcc
using the-Wall
flag tells us (see it live):