1

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

4

3 回答 3

2

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

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

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

虽然后者现在已经过时:来自第 6.11.6 节 Function declarators C11 spec n1570 draft

使用带空括号的函数声明符(不是原型格式参数类型声明符)是一个过时的特性。

于 2016-03-15T08:06:06.350 回答
2

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

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

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


笔记:

根据C11第 6.9.1 章

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

于 2016-03-15T08:07:10.783 回答
-2

考虑这段代码:

//void Test(int a);

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

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

如果取消注释第一行void Test(int a);,它将不再编译,因为现在编译器知道这Test是一个返回 anint并只接受一个int参数的函数,并且当我们Test()不带参数调用时,编译器可能会抛出错误,因为调用时的参数不匹配声明函数时的参数。

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

于 2016-03-15T08:14:49.257 回答