为什么要在Visual Studio中编译:
void foo(int a) {}
int main() {
foo(1,2);
}
有警告
source_file.c(4) : warning C4020: 'foo' : too many actual parameters
但是为什么它不是一个错误,因为gcc / clang是这样的?
我知道K& R风格的函数定义,但这只适用于需要可变数量参数的foo()
。
标准中的引文允许这样做非常感谢。
答案 0 :(得分:3)
这不仅仅是MSVC。
如果您的函数定义低于调用站点并且没有原型,则GCC接受它。 C总是允许调用未声明的函数。它从呼叫站点推断出原型。所以我认为行为与那个方面有关(虽然当我在GCC中将函数移动到调用站点之上时,它会变为错误,这对于C99来说是有意义的)。尽管如此,这应该是未定义的行为(参数的参数数量不同)。
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);
我发现了这个
6.7.5.3p15:
[...]如果一种类型具有参数类型列表而另一种类型具有参数类型列表 由包含(可能为空)的函数定义指定 标识符列表[这是你的情况],两者都应该同意 参数的数量,以及每个原型参数的类型 与应用程序产生的类型兼容 默认参数促销对应的类型 标识符。 [...]
....但这段不是约束的一部分。违反a 约束部分之外的“应”是未定义的行为,而不是 必须被诊断的行为(4p2)。
我引用了这个:http://compgroups.net/comp.lang.c/why-is-this-not-an-error-in-visual-c/732881
您的里程可能会有所不同。
简而言之,显然唯一的要求是编译器咆哮你的树皮定义。在VS 2013中,它被视为错误。
对于参数发生的情况,由于变量参数列表在C中工作的原因相同,调用站点应该推送额外的参数,但被调用者不会意识到它(只是在这里猜测)。虽然它有效,但并不意味着它是定义的行为。