Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 763
Alfred Avatar asked Aug 16 '13 16:08

Alfred


2 Answers

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;
    
like image 164
Grijesh Chauhan Avatar answered Nov 15 '22 04:11

Grijesh Chauhan


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.

like image 38
Chris Dodd Avatar answered Nov 15 '22 05:11

Chris Dodd