Visual C接受错误数量的参数? [英] Visual C accepting wrong number of arguments?

查看:71
本文介绍了Visual C接受错误数量的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么要在Visual Studio中进行编译?

Why does this compile in Visual Studio:

void foo(int a) {}

int main() {
    foo(1,2);
}

有警告

source_file.c(4) : warning C4020: 'foo' : too many actual parameters

但是为什么不像gcc/clang这样的错误呢?

but why isn't it an error as it is the case with gcc/clang?

我知道K& R样式的函数定义,但这仅适用于foo(),它需要使用可变数量的参数.

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.

推荐答案

这不仅是MSVC.

如果您的函数定义在调用站点下面,并且没有原型,则GCC会接受它. C始终允许调用未声明的函数.它从调用站点推断出原型.因此,我认为行为与该方面有关(尽管当我将函数移到GCC中的调用站点上方时,它变成了错误,这对于C99有意义).尽管如此,这应该是未定义的行为"(args的数量与参数的数量不同).

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);

我发现了

6.7.5.3p15:

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. [...]

....但此段不是约束的一部分.违反 约束部分外的应"是未定义的行为,不是 必须被诊断的行为(4p2).

.... 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).

我引用了以下内容:您的里程可能会有所不同.

Your mileage may vary.

简而言之,显然唯一的要求是编译器会咆哮着要求您定义树皮.在VS 2013中,它被视为错误.

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.

就参数发生什么而言,出于可变参数列表在C语言中起作用的相同原因,调用站点应推送额外的参数,但被调用方将不知道(只是在这里猜测).尽管它可以工作,但这并不意味着它是已定义的行为.

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.

这篇关于Visual C接受错误数量的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆