Alfred
Alfred

Reputation: 69

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;
}

Upvotes: 5

Views: 16612

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126536

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.

Upvotes: 4

Grijesh Chauhan
Grijesh Chauhan

Reputation: 58291

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;
    

Upvotes: 4

Related Questions