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

2019-01-19 18:54发布

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 ?

10条回答
Deceive 欺骗
2楼-- · 2019-01-19 19:13

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.

查看更多
成全新的幸福
3楼-- · 2019-01-19 19:16

what warnings/messages did you get using your compilers? i ran this through gcc (Ubuntu 4.8.2-19ubuntu1) and got a warning

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

and running it also "garbage output". here, the gcc is so clever to parse the format expression and notifies the coder to provide a matching number of arguments.

what i think happens: the function signature of printf is independent from the behaviour of the compiled code. at compile time, all the compiler cares is to check if at least one argument is there and continues. however, the compiled function will first parse the format expression and, dependent on that, read further arguments from the functions' arguments stack. therein it simply expects appropriately put values (int, float etc) and uses them. so if you dont specify the argument, no place on the function call stack is reserved and printf still reads random memory (in this case at the first location). this also explains the "garbage" output, which will differ each time you call the binary. you can even extend the code to

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

and get two different garbage numbers :)

then again it will depend on the environment/process/compiler which values will be read. "unspecified behaviour" is what describes this effect best, sometimes zero, sometimes other.

i hope this clarifies your issue!

查看更多
Summer. ? 凉城
4楼-- · 2019-01-19 19:17

Using g++ with commandline parameter -Wall produces the following diagnostics:

g++ -Wall   -c -g -MMD -MP -MF "build/Debug/MinGW-Windows/main.o.d" -o build/Debug/MinGW-Windows/main.o main.cpp
main.cpp: In function 'int main(void)':
main.cpp:17:16: warning: format '%d' expects a matching 'int' argument [-Wformat=]
     printf("%d");
                ^

That's pretty useful, isn't it?

gcc/g++ also check if the format specifiers actually match the parameter types. This is really cool for debugging.

查看更多
成全新的幸福
5楼-- · 2019-01-19 19:20

According to this documentation, the additional arguments must be at least as many as the format specifiers in the first argument. This seems to be undefined behaviour.

查看更多
登录 后发表回答