【问题标题】:Visual C accepting wrong number of arguments?Visual C 接受错误数量的参数?
【发布时间】:2014-12-21 14:17:49
【问题描述】:

为什么会在 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(),它需要可变数量的参数。

如果标准允许这样做,我们将不胜感激。

【问题讨论】:

  • 如果启用/WX,则可以将其视为错误,这是首选。
  • 我实际上并没有使用 VS。我从一个能够用 VS 编译它的学生那里得到了代码,但是我从 gcc 和 clang 那里得到了错误。抛出错误似乎是我做的唯一合理的事情,所以我试图了解 VS 在那里做了什么。 2 去哪儿了?
  • 仅供参考:VS2013 会将其视为编译器错误:error C2660: 'foo' : function does not take 2 arguments.
  • 标准没有定义“编译器错误”。它只需要“诊断”。诊断可能是警告或错误;该标准不区分它们。该标准也不要求编译器拒绝生成诊断的程序。
  • @RaymondChen 谢谢 - 我完全没有意识到这一点。

标签: c visual-studio


【解决方案1】:

这不仅仅是 MSVC。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    相关资源
    最近更新 更多