2010-11-09 64 views
1

我有以下代码:警告关于C函数指针

#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指针兼容吗?

回答

1

你也可以这样做:

free_func((int *)arg); 

不过,请注意转换一个void *至T *(在这种情况下int *) 是不安全由于使用T *的副作用,实际上并不指向T

例如

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); 
3

你可以将类型转换并不意味着编译器会很乐意为你做。

在这种情况下,函数指针定义不匹配。 C不会假定声明为int*的函数会很高兴,而不是void*,尽管这两种类型之间的转换是隐含的。 C是如何处理函数指针的,这是一个微妙的问题。

如果你想这没有警告的工作,你将不得不投,像这样:

func2(%a, (func_t)func); 
+0

好的,所以类型之间的转换是隐含的,但涉及这些类型的函数签名之间不是隐含的?反直觉。 – 2010-11-09 20:52:10

+0

这就是它的要义。是的,我从来没有说C很直观。 ;) – cdhowie 2010-11-09 20:53:07

+0

我也不明白为什么我以前从来没有遇到过......可能与VC++没有抱怨它有关。 – 2010-11-09 20:54:39

1

指针类型只有当它们的基本类型兼容兼容,intvoid不兼容。

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

0

如果更改FUNC的声明/定义

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

一切都按你所期望的。

+0

队长明显? – 2010-11-09 22:55:17