Visual C accepting wrong number of arguments?

2019-01-19 08:03发布

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.

1条回答
Lonely孤独者°
2楼-- · 2019-01-19 08:34

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.

查看更多
登录 后发表回答