【问题标题】:Get incompatible-pointer-types warning except void *获取除 void * 之外的不兼容指针类型警告
【发布时间】:2021-05-27 22:27:12
【问题描述】:
#include <stdio.h>

void fun1(int *c){return;}
void fun2(void *p){return;}
void fun3(void **p){return;}

typedef void (* myfunptr)(void *);

void fun4(myfunptr b){
return;
}

    int
    main(){
    
       int *p;
       void *q = p;
    
       fun1(p); //no warning
    
       fun1(q); //no warning
    
       fun2(p); //no warning
    
       fun2(q); //no warning
    
       fun3(&p); //warning - incompatible pointer types
    
       fun3(&q); //no warning
       
       fun4(fun1); //warning - incompatible pointer types
    
       fun4(fun2); //no warning 
    
       return 0;
    
    }

我意识到fun3(&amp;p) 的警告是因为void ** 不是像void * 这样的通用指针。但是,我有点疑惑为什么在fun4(fun1) 的情况下会出现警告,因为void *int * 是在没有警告的情况下隐式转换的。

我的下一个问题是,除了void *void ** 涉及的所有不兼容指针转换,我是否会收到“不兼容类型”的警告。因为使用-Wno-incompatible-pointer-types 会禁用所有类型转换的警告。

【问题讨论】:

    标签: c function-pointers implicit-conversion void-pointers


    【解决方案1】:

    尽管int* 可以隐式转换为void*(正如您所说,没有警告),但您的fun4(fun1); 语句的情况却大不相同。在这种情况下,您正在隐式转换 函数指针 - 在指向具有不同签名的函数的指针之间。

    关于指向不同类型函数的指针之间的兼容性的更全面讨论可以在这里找到:Casting a function pointer to another type

    虽然,在您的特定情况下,应该通过 fun4 指针参数调用 fun1 时没有问题(因为,正如你所说,前者有一个与之兼容的参数列表为fun4 参数提供),编译器仍然(恕我直言)“有理由”向您提供fun1 的签名与预期的myfunptr 的签名不同的警告。

    【讨论】:

      【解决方案2】:

      乐趣1(p); //没有警告

      int*显然兼容int*

      fun1(q); //没有警告

      void*,作为一种特殊情况类型,与所有其他对象指针类型兼容,并隐式转换为/从其他指向对象类型的指针。

      fun2(p); //没有警告

      如前所述,void*int* 可以相互隐式转换。

      fun2(q); //没有警告

      void*显然兼容void*

      fun3(&p); //警告 - 不兼容的指针类型

      void* 的特殊规则不适用于“递归”。 void** 不是通用对象指针类型。它与int** 不兼容。您会看到一些垃圾 API 仍在进行此类转换(CUDA 等),但它们很糟糕并且依赖于非标准行为。

      fun3(&q); //没有警告

      void** 显然与void** 兼容。

      乐趣4(乐趣1); //警告 - 不兼容的指针类型

      函数指针需要指向相同的函数才能兼容。相同的返回类型,相同的参数,相同的限定符。

      乐趣4(乐趣2); //没有警告

      您提供了预期类型的​​函数指针,所以没问题。请注意,在这种情况下,fun2 从函数“衰减”为函数指针,因为它用于表达式。


      另外请注意void* 是通用的object 指针。不能将其作为通用指针类型与函数指针混合使用!

      【讨论】:

        猜你喜欢
        • 2015-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多