简体   繁体   中英

invalid conversion from void* to void(*)(void*)[-fpermissive]

this question was asked in relation to threads, but I have a simpler case.(beginner)
I tried the code in different compilers for c++ but would not work.
please advise how to replace the line: 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;
}

The problem is that callback is not a void pointer, its a pointer to a function. So to shut up the warning, you need to cast to the correct type:

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

Note that this will get rid of the warning, but is not guaranteed to work -- while you can cast a function pointer type to a different function pointer type, calling the resulting function pointer (without first casting it back) is Undefined Behavior.

Now on most machines, all pointers have the same internal bit representation. In particular, MyMsg * and void * will be the same, so this will in fact work fine. But its not guaranteed. To be strictly standards conforming, you should change myfunc to be:

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

Now it has the same signature as callback , so you can assign it without casting. The cast inside myfunc is probably a noop, but needs to be there for strict conformance.

Yes, your typecasting is wrong:

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

You can do like:

  1. Define a new type:

     typedef void (*functiontype) ( void*); 
  2. Typecast as follows:

     callback = (functiontype)myfunc; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM