具有const参数的函数指针是否可以用作具有nonconst参数的函数指针?

ant*_*ony 16 c const function-pointers

也许标题本身并不清楚......我有一个函数f(由某些库提供),它将一个参数作为签名的函数指针void g(int*),即

void f(void (*g)(int*));
Run Code Online (Sandbox Code Playgroud)

但是,我想使用g带有签名的函数(我定义的)来使用它void g(const int*).先验的,我看不出如何能违反任何常量,正确性,因为所有的签名f说的是,g将只与一个(非叫const)int*(非const),而事实上我可以调用一个void (const int*)函数用不const int*论证.

但海湾合作委员会抱怨并说,

expected 'void (*)(int *)', but argument is of type 'void (*)(const int *)'
Run Code Online (Sandbox Code Playgroud)

我看不出这个投诉是如何合法的,所以有人知道我对此的理解是否错误,或者是否有办法解决?

Die*_*Epp 6

您似乎找到了编译器编写者和标准编写者未考虑的内容.从C99草案n1256,§6.7.5.3第15段,

相应的参数应具有兼容的类型.

注意const int *与之不兼容int *.但是,int *可能会被转换为const int *.从§6.3.2.3第2段开始,

对于任何限定符q,指向非q限定类型的指针可以转换为指向该类型的q限定版本的指针

用于推断替换从相同类型的合格或非限定版本派生的类型何时可接受的更复杂的规则在标准中根本不存在.因此,您的代码在技术上违反了标准.

我的结论:在我看来,这个错误应该被编译器视为"迂腐":你的代码在技术上并不符合标准,但意思是明确的,代码是绝对安全的.随意向您的编译器供应商写一个功能请求.有许多不一致的做法,如果没有,就不会产生警告-pedantic.

作为最后一点,我和Clang一起编辑,编辑告诉我警告是迂腐的.但是,我没有要求迂腐警告......所以似乎无法将其关闭.

warning: incompatible pointer types passing 'void (int const *)', expected 'void (*)(int *)'
      [-pedantic]

解决方法:使用显式强制转换.

void g(const int *);

f((void (*)(int *)) g);
Run Code Online (Sandbox Code Playgroud)