关于C函数指针的警告

时间:2010-11-09 20:42:43

标签: c warnings

我有以下代码:

#include <stdlib.h>
#include <stdio.h>

typedef void (*func_t)(void * data);

void func2(int * arg, func_t free_func) {
        free_func(arg);
}

void func(int * a) {
        printf("%d\n", *a);
}

int main(int argc, char ** argv) {
        int a = 4;
        func2(&a, func);
        return 0;
}

编译给了我 警告:从不兼容的指针类型

传递`func2'的arg 2

为什么? int指针不应该与void指针兼容吗?

4 个答案:

答案 0 :(得分:3)

您可以转换类型并不意味着编译器会很乐意为您执行此操作。

在这种情况下,函数指针定义不匹配。 C不会假设声明采用int*的函数会使用void*而感到高兴,即使这两种类型之间的转换是隐式的。这是C处理函数指针的一个微妙的问题。

如果你想让它在没有警告的情况下工作,你必须这样投射:

func2(%a, (func_t)func);

答案 1 :(得分:1)

你也可以这样做:

free_func((int *)arg);

注意虽然将void *转换为T *(在本例中为int *)  不安全是由于使用实际上并未指向T的T *的副作用

e.g。

char i = 0;
char j = 0;    
char* p = &i;
void* q = p;
int* pp = q;    /* unsafe, legal C, not C++ */
printf("%d %d\n",i,j);
*pp = -1;   /* overwrite memory starting at &i */
 printf("%d %d\n",i,j);

答案 2 :(得分:1)

仅当指针类型的基本类型兼容且intvoid不兼容时,指针类型才兼容。

此外,int和void指针可能具有不同的大小和表示。

答案 3 :(得分:0)

如果您将func的声明/定义更改为

void func(void * a) {
        printf("%d\n", *(int*)a);
}

一切都按照您的预期运作。