【问题标题】:Why can functions with no arguments defined be called with any number of arguments? [duplicate]为什么可以使用任意数量的参数调用没有定义参数的函数? [复制]
【发布时间】:2016-06-30 13:16:36
【问题描述】:

在 C 中,如果一个函数定义为 0 个参数(空参数列表),则调用任意数量的参数,gcc 不会给出任何错误。为什么会这样?

【问题讨论】:

  • 编译时启用所有警告(-Wall)。
  • 请出示MCVE
  • 因为这就是语言的设计方式。你是在问为什么语言是这样设计的?
  • -Wall编译你会得到:error: void value not ignored as it should be
  • C 规范说,声明的函数没有任何参数(甚至没有 void 参数)采用未指定数量的参数。如果你想明确地说一个函数不带参数,你需要指定一个没有名称的void 参数类型。

标签: c function function-declaration function-definition


【解决方案1】:

因为这是 C 规范定义函数的方式。

如果您希望函数不带参数,请在参数列表中明确指定 void

如果您希望函数采用可变数量的参数,请使用可变参数...。或者在古代 C 中,您可以将参数列表留空,编译器将对每个参数应用默认提升。

虽然后者现在已经过时:来自第 6.11.6 节函数声明符 C11 规范 n1570 草案

使用带空括号的函数声明符(不是 原型格式参数类型声明符)已过时 功能。

【讨论】:

    【解决方案2】:

    TL;DR - int func(void) {..int func() {.. 不一样。

    • 在第一种情况下,通过明确提及 void 作为参数类型(不需要标识符)注意该函数被定义为没有输入参数,因此在调用它时不应该传递任何参数。

    • 在后一种情况下,不会检查传递的参数数量,因此允许传递任意数量和类型的参数。


    注意:

    根据C11,第 §6.9.1 章

    如果声明符包含参数类型列表,则每个参数的声明应 包括一个标识符,除了由单个参数组成的参数列表的特殊情况 void 类型的参数,在这种情况下不应有标识符。无申报清单 应遵循。

    【讨论】:

      【解决方案3】:

      考虑这段代码:

      //void Test(int a);
      
      int main()
      {
        int a = 0;
        Test();
        return 0;
      }
      

      它将编译(主要是根据编译器、设置等发出警告),因为编译器假定 Test 是一个接受任意数量参数并返回 int 的函数。这也称为“隐式声明”。永远不要使用 C 语言的这个过时特性。

      如果您取消注释第一行 void Test(int a);,它将不再编译,因为现在编译器知道 Test 是一个返回 int 并只采用一个 int 参数的函数,正如我们所说的 @ 987654328@ 不带参数,编译器会抛出错误,因为调用时的参数与函数声明时的参数不匹配。

      现在我们可以问一个问题:为什么首先允许隐式声明?嗯,这就是语言的设计方式。 IMO 这是一个设计错误。

      【讨论】:

      • 这可能是真的,但我看不出它是如何回答这个问题的。
      猜你喜欢
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-02
      相关资源
      最近更新 更多