对于代码:
int hi(int);
int hi();
int main()
{
hi(3);
}
我没有收到任何编译错误(调用
hi()
;没有参数确实会出现编译错误)。
我预计编译器会抱怨该函数已经被不同地声明了。知道为什么会这样吗?
你可以多次声明相同的符号,只要声明不相互矛盾,你就不会出错。
原因
int hi();
不矛盾
int hi(int);
是因为完全没有任何参数的声明意味着你说你真的不知道有多少参数或它们是什么类型。这与第一个声明并不矛盾。并且因为您已经声明了
hi
,编译器将简单地使用该声明。
如评论中所述,这将随着 C23 标准而改变。它采用了 C++ 的语义,没有显式参数意味着
void
,所以
int hi();
将等同于
int hi(void);
这当然意味着这两个声明将相互矛盾。
如果其中只有一个函数定义,您可以使用多个函数声明。
在 C 中定义了兼容类型的概念。
来自C11标准(6.2.7兼容型和复合型)
1 如果类型相同,则两个类型具有兼容类型
和(6.7声明)
4 同一范围内引用同一对象的所有声明或 函数应指定兼容类型。
最后(6.7.6.3 函数声明符(包括原型))
- ... 如果一种类型有参数类型列表,另一种类型 由不属于函数的函数声明符指定 定义并且包含一个空的标识符列表,参数 列表不应有省略号终止符和每个列表的类型 参数应与产生的类型兼容 默认参数促销的应用。
在这两个函数声明中
int hi(int);
int hi();
返回类型兼容*它们是相同的)。并且第一个函数声明的参数具有返回类型
int
,对应于整数促销的类型。
来自 C11 标准 6.5.2.2 函数调用)
6 如果表示被调用函数的表达式的类型是 不包括原型,整数提升是在 每个参数和具有 float 类型的参数都被提升为 双倍的。这些称为默认参数提升(
在 C23 标准中,相对于函数声明做了以下更改
—参数列表为空的强制函数声明是 与仅包含一个 void 的参数列表一样对待;
所以根据 C23 标准,这些函数声明
int hi(int);
int hi();
相当于
int hi(int);
int hi( void );
所以他们声明了两个不同的函数,编译器应该发出一条消息。