我有这样一段代码:
int foo() { return 0; }
int main()
{
int (*float_function)(float) = foo;
}
使用x86-64 GCC 12.2
编译时,如果使用-Wall
,则会生成警告(Link):
警告:从不兼容的指针类型“int()()”初始化“int()(float)"[-Wincompatible-pointer-types]
但是,当我从float
更改为double
(Link)时:
int foo(){ return 0;}
int main()
{
int (*double_function)(double) = foo;
}
警告现在消失了。
但我认为这两个都应该得到警告。
我哪里错了吗?为什么GCC不抱怨第二个例子?
1条答案
按热度按时间irlmq6kh1#
声明
int foo()
时未指定其参数。这是一个过时的功能,允许您使用任何参数调用它。调用函数时,整数参数将提升为int
(如果需要),float
参数将提升为double
。因此,该函数不可能接收
float
参数,这使得它与int (*)(float)
不兼容,但与int (*)(double)
不兼容。如果你想要一个不带参数的函数,那么就声明为
int foo(void)
,这会使它与两者都不兼容。注意,即使使用
double
,代码也不是有效的C代码,因为int foo() {...}
是一个函数定义,所以编译器知道它没有参数(参见chux的注解,下面是标准参考)。如果用声明
int foo();
代替,并将定义放在其他地方,则上述内容是正确的。在这种情况下,相关的标准引用(C17 6.7.6.3/15)为:为了使两个函数类型兼容,[...]如果一个类型具有参数类型列表,而另一个类型由不属于函数定义的函数声明符指定,并且包含空标识符列表,[...]则每个参数的类型都应与应用默认参数提升所产生的类型兼容。