Visual C接受错误的参数数量?

时间:2014-10-26 05:12:48

标签: c visual-studio

为什么要在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()

标准中的引文允许这样做非常感谢。

1 个答案:

答案 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中工作的原因相同,调用站点应该推送额外的参数,但被调用者不会意识到它(只是在这里猜测)。虽然它有效,但并不意味着它是定义的行为。