(void *)和(void(*)(参数类型))cast之间有什么区别?

时间:2015-06-01 10:05:51

标签: c++ c pointers

void funcPtr(int a);

int main(){
   int k=1;
   void (*funcPtr2)(int);

   funcPtr2 = (void*)(funcPtr);
   // funcPtr2 = (void(*)(int))(funcPtr);

   (*funcPtr2)(k);
   return 0;
}

void funcPtr(int a){
   printf("%d", a);
}

函数指针类型转换中(void*)(void(*)(argument type)之间的区别是什么?

因此,它不会发出警告。

这是错的吗?关于(void*)类型转换

3 个答案:

答案 0 :(得分:7)

  

这是错的吗? about(void *)类型转换

是的,是的。

C标准不允许将函数指针转换为对象指针或它们之间的赋值。如果您提高了编译器警告级别,则可能会收到警告/错误,例如编译:

gcc -Wall -Wextra -pedantic-errors -std=c11 file.c

我不确定你为什么要考虑转换函数指针。如果函数指针类型与函数匹配,只需指定它:

 funcPtr2 = funcPtr;

除了:

您可以像使用函数一样使用函数指针:

 funcPtr2(k);

并使用main的标准原型,例如:

int main(void)

答案 1 :(得分:1)

这是dlsym的问题,声明为void *dlsym(void *restrict handle, const char *restrict name)dlsym返回指向name中定义并可通过handle访问的名为gcc的函数的指针 然而,正如@BlueMoon所述,这在ISO C中没有定义,fptr = (int (*)(int))dlsym(handle, "my_function");确实抱怨如果迂腐。 POSIX试图解决这个问题,并要求符合要求的实现,以使其无限期地定义良好的定义。

来自POSIX

  

请注意,从void *指针转换为函数指针,如:

     

void**

     

未由ISO C标准定义。该标准要求此转换在符合要求的实现中正常工作。

使该转换符合的另一种方法是首先将函数指针转换为void funcPtr(int a); /* symbol to extract */ int main(void) { void (*fn)(int); *(void**)(&fn) = dlsym(your_handle, "funcPtr"); fn(5); } ,然后取消引用它。这应该是明确的。 在你的情况下,

\r\n

答案 2 :(得分:0)

(void*)

将指针转换为指向void 的指针,或指向通用指针。

void(*)(int)

是一个函数指针,它指向一个带有int参数且不返回任何内容的函数。

int fn(float f) { return f * 3.14; }

void* ptr = fn;

ptr设为fn的第一条机器指令的地址,但不允许您使用它。

int(*ptr)(float) = fn;
// or
typedef int(FnPtr)(float);
FnPtr* ptr = fn;

以编译器知道指向哪种函数调用的方式获取地址,以便您可以调用函数

int n = ptr(2.5);

对于像

这样的事情有用
void get_data(int socket, int timeout, void(*callback)(char*, size_t));

这是一个我可以传递另一个函数的函数。

void recv_data(char* data, size_t len)
{
    ...
}

...

get_data(socket, 60, recv_data);