在 C 中,如果一个函数定义为 0 个参数(空参数列表),则调用任意数量的参数,gcc 不会给出任何错误。为什么会这样?
3 回答
因为这是 C 规范定义函数的方式。
如果您希望函数不带参数,请void
在参数列表中明确指定。
如果您希望函数采用可变数量的参数,请使用可变参数...
。或者在古代 C 中,您可以将参数列表留空,编译器将对每个参数应用默认提升。
虽然后者现在已经过时:来自第 6.11.6 节 Function declarators C11 spec n1570 draft
使用带空括号的函数声明符(不是原型格式参数类型声明符)是一个过时的特性。
TL; DR -int func(void) {..
并且int func() {..
不一样。
在第一种情况下,通过显式提及
void
参数类型(不需要标识符)注意该函数被定义为没有输入参数,因此在调用它时不应传递任何参数。在后一种情况下,不检查传递的参数数量,因此您可以传递任意数量和类型的参数。
笔记:
根据C11
第 6.9.1 章
如果声明符包含参数类型列表,则每个参数的声明都应包含一个标识符,但参数列表由一个类型的单个参数组成的特殊情况除外
void
,在这种情况下不应有标识符。不得附有申报清单。
考虑这段代码:
//void Test(int a);
int main()
{
int a = 0;
Test();
return 0;
}
它将编译(主要是根据编译器、设置等发出警告),因为编译器假定这Test
是一个接受任意数量参数并返回int
. 这也称为“隐式声明”。你永远不应该使用 C 语言的这个过时的特性。
如果取消注释第一行void Test(int a);
,它将不再编译,因为现在编译器知道这Test
是一个返回 anint
并只接受一个int
参数的函数,并且当我们Test()
不带参数调用时,编译器可能会抛出错误,因为调用时的参数不匹配声明函数时的参数。
现在我们可以问一个问题:为什么首先允许隐式声明?嗯,这就是语言的设计方式。IMO 这是一个设计错误。