Reputation: 8333
Why does this compile in Visual Studio:
void foo(int a) {}
int main() {
foo(1,2);
}
There is a warning
source_file.c(4) : warning C4020: 'foo' : too many actual parameters
but why isn't it an error as it is the case with gcc/clang?
I am aware of K&R-style function definitions, but that would only apply for foo()
which would take a variable number of arguments.
Citations from the standard allowing this would be greatly appreciated.
Upvotes: 4
Views: 1468
Reputation: 20842
This is not just MSVC.
GCC accepts it, if your function definition is below the call site and there is no prototype. C has always allowed calling an undeclared function. It infers the prototype from the call-site. So I think the behavior is related to that aspect (though when I move the function above the call-site in GCC, it changes to an error, which makes sense for C99). This should be Undefined Behavior, nonetheless (different number of args than parameters).
int main()
{
foo(1,2,3);
}
void foo(int a, int b)
{
}
f.c:6:6: warning: conflicting types for ‘foo’ [enabled by default]
void foo(int a, int b)
^
f.c:3:4: note: previous implicit declaration of ‘foo’ was here
foo(1,2,3);
I found this
6.7.5.3p15:
[...] If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list [this is your situation], both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. [...]
.... but this paragraph is not part of a constraint. Violating a "shall" outside a constraint section is undefined behavior, not must-be-diagnosed behavior (4p2).
I quoted this from : http://compgroups.net/comp.lang.c/why-is-this-not-an-error-in-visual-c/732881
Your mileage may vary.
In short, apparently the only requirement is that the compiler barks at you for some definition of bark. In VS 2013 it is treated as an error.
As far as what happens to the argument, for the same reason that variable argument lists work in C, the call site should push the extra argument, yet the callee will not be aware of it (just guessing here). Though it works, it does not mean it is defined behavior.
Upvotes: 4