I was answering a question and noticed something that seemed odd. The code in question was more complicated, but the observation boils down to the fact that this compiles in MSVC 14.0:
#include <stdio.h>
void foo(int);
int main()
{
foo(66);
getchar();
}
void foo(const char* str, int x)
{
printf("%s %d\n", str, x);
}
This code produces undefined behavior, because the value of str
in foo
is 66
, which doesn't point to a valid null-terminated string, so in practice we (most likely) get a segfault.
As stated, I used Visual Studio 2015 - MSVC 14.0 - to compile this. I'm compiling as the code as C. If we try GCC 5.1, it fails.
At first I thought this was one of the weird thing C allowed in its early days and has been left in it not to break old code (such as implicit function prototypes). But here, we have a prototype AND a definition with the same name, yet they are not compatible. How come this is not rejected by the compiler? C doesn't allow function overloading, so two identifiers with identical names should not be legal.
Why does MSVC not reject this code? Is there an explanation for this behavior? Is this explicitly allowed in one of the standards?
EDIT: Because there seems to be much confusion in the comments, I would like to clarify. I know how to avoid these kinds of mistakes, I always compile with the maximum warning level and treat warnings as errors; this is not the point here. The question is purely theoretical: I want to know whether this behavior is legal and defined in the C Standard. Because two C compilers behave differently when given the same code, something is wrong.
According to C11 (N1570 draft) 6.7/4 Declarations (within Constraints section):
All declarations in the same scope that refer to the same object or function shall specify compatible types.
The definition serves also as declaration, hence the language constraint is violated.
For that, the conforming implementation is obligated to produce a diagnostic message, that is in implementation-defined manner, as of 5.1.1.3 Diagnostics:
A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint (...)
That's all. A diagnostic message may be of any kind, they may even send you a letter, if they like so.