无效转换从void *到void(*)(void *)[ - fpermissive]

时间:2013-08-16 16:33:46

标签: c++ c pointers function-pointers

这个问题与线程有关,但我有一个更简单的案例。(初学者)
我在c ++的不同编译器中尝试了代码,但是无法工作 请告知如何更换该行:callback = (void*)myfunc; // - > error

typedef struct _MyMsg {
        int appId;
        char msgbody[32];
} MyMsg;    
void myfunc(MyMsg *msg)
{
        if (strlen(msg->msgbody) > 0 )
                printf("App Id = %d \n Msg = %s \n",msg->appId, msg->msgbody);
        else
                printf("App Id = %d \n Msg = No Msg\n",msg->appId);
}    
/*
 * Prototype declaration
 */
void (*callback)(void *);    
int main(void)
{
        MyMsg msg1;
        msg1.appId = 100;
        strcpy(msg1.msgbody, "This is a test\n");    
        /*
         * Assign the address of the function 'myfunc' to the function
         * pointer 'callback'
         */                 
//line throws error: invalid conversion from void* to void(*)(void*)[-fpermissive]    
        callback = (void*)myfunc; //--> error               
        /*
         * Call the function
         */
        callback((MyMsg*)&msg1);    
        return 0;
}

2 个答案:

答案 0 :(得分:4)

问题是callback不是void指针,它是指向函数的指针。因此,要关闭警告,您需要转换为正确的类型:

callback = (void (*)(void *))myfunc;

请注意,这将消除警告,但不能保证工作 - 虽然您可以将函数指针类型强制转换为其他函数指针类型,但调用结果函数指针(不先将其强制转换)是未定义的行为。

现在在大多数机器上,所有指针都具有相同的内部位表示。特别是,MyMsg *void *将是相同的,所以这实际上可以正常工作。但它不能保证。要严格遵守标准,您应将myfunc更改为:

void myfunc(void *msg_)
{
    MyMsg *msg = (MyMsg *)msg_;
    :

现在它与callback具有相同的签名,因此您可以在不进行转换的情况下分配它。 myfunc内的演员可能是一个noop,但需要严格遵守。

答案 1 :(得分:3)

是的,你的类型转换是错误的:

 callback = (void*)myfunc;
              ^
               is void*  but Not void (*)(void*)

你可以这样做:

  1. 定义新类型:

    typedef  void (*functiontype)  ( void*);
    
  2. Typecast如下:

    callback = (functiontype)myfunc;