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