为什么gcc
可以编译以下代码#include <stdio.h>
int func();
int func(int a) { return 1; }
int main() {
func(10);
return 0;
}
但如果我添加char func();
,gcc会说conflicting types for ‘func’
答案 0 :(得分:11)
这不是重载,因为你不能在没有参数的情况下调用func()
。这是具有兼容的函数声明符的单个函数的特例,如标准中所述:
如果一个类型具有参数类型列表而另一个类型由函数声明符指定,该函数声明符不是函数定义的一部分并且包含空标识符列表,则参数列表不应具有省略号终止符和类型每个参数应与应用默认参数促销产生的类型兼容。
将回复类型从int
更改为char
是违反此规则的一种方法。打破它的另一种方法是提供除int
以外的参数类型:
int func();
int func(char a) { return 1; } // Does not compile
如果您想声明一个不带任何参数的函数,声明符应该如下:
int func(void);
现在声明func
int
将导致编译时错误:
int func(void);
int func(int a) { return 1; } // Does not compile
答案 1 :(得分:1)
您的第一个声明是K&amp; R声明,而下一个声明(带有定义)是ANSI原型。
如果它们兼容,可以在KR decl和ANSI原型之间进行任何组合。
C类型检查器将两者结合起来并保留ANSI原型。这称为composite type
。
以下是如何计算ANSI和K&amp; R decl:
之间组合的复合类型6.2.7兼容类型和复合类型
3 ...如果只有一种类型是带参数类型列表的函数类型(a 函数原型),复合类型是一个函数原型 参数类型列表。
要检查2个函数声明是否兼容,必须应用6.7.6.3 Function declarators
15要兼容两种功能类型,两者都应指定 兼容的返回类型.146)此外,参数类型列出,如果 两者均存在,应在参数数量和使用中达成一致 省略号终结符;相应的参数应具备 兼容类型。
这就是为什么您的原型可以与K&amp; R decl结合使用,因为它们被视为兼容。