为什么具有空参数列表的函数原型与具有char参数的函数原型冲突?

Ink*_*ane 5 c standards gcc clang c11

使用下面的代码,使用-std = c11调用的clang和gcc都会抱怨foo的冲突类型.

int foo();

int main(void) {
  return foo(0);
}

int foo(char a) {
   return a;
}
Run Code Online (Sandbox Code Playgroud)

根据/sf/answers/976556031/中的答案,在(较旧的?)C标准中,当没有给出变量类型时,假设类型为int.但是,C11标准草案(http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf),第6.7.6.3节,14美元表示

函数声明符中的空列表不是该函数定义的一部分,它指定不提供有关参数数量或类型的信息.

由此我得出结论,上面的代码实际上应该是有效的.或者我错过了标准的其他相关部分?

Eri*_*hil 12

C 2011(N1570)6.7.6.3 15:

要使两种函数类型兼容,两者都应指定兼容的返回类型.此外,参数类型列表(如果两者都存在)应在参数的数量和省略号终止符的使用中一致; 相应的参数应具有兼容的类型.如果一个类型具有参数类型列表而另一个类型由函数声明符指定,该函数声明符不是函数定义的一部分并且包含空标识符列表,则参数列表不应具有省略号终止符,并且每个参数的类型应为与应用默认参数促销产生的类型兼容.... [强调添加.]

char被提升为int,因此char a与空列表不兼容.int a将会; int foo(); int foo(int a);被允许.

本质上,原因是,如果你声明一个函数int foo()然后调用它,比如说int foo(3),编译器必须知道传递它的内容.从历史派生的规则是执行默认参数提升.因此int foo(3)被调用就像它一样int foo(int).

然后,如果稍后定义函数int foo(char),则定义将与调用不匹配.在许多C实现中,a char和a int可以放在同一个地方用于调用函数,但是C实现可以做一些不同的事情.A float和a double将是一场更大的冲突.