Warning: Assignment from Incompatible Pointer Type [enabled by default] while assigning Function Address to Function Pointer

51,529

Solution 1

The warnings appear due to the following quote from the C Standard

6.3.2.3 Pointers

8 A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

That two functions would be compatible their parameters shall have compatible types

6.7.6.3 Function declarators (including prototypes)

15 For two function types to be compatible, both shall specify compatible return types.146) Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types.

In your functions parameters are declared as pointers. So that they (pointers) would be compatible they shall be pointers to compatible types

6.7.6.1 Pointer declarators

2 For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.

However types int or char on the one hand and type void on the other hand are not compatible types.

You could define your functions the following way

void intSwap( void *a, void *b )
{
    int *x = a;
    int *y = b;

    *x = *x + *y;
    *y = *x - *y;
    *x = *x - *y;
}

void charSwap( void *a, void *b )
{
    char *c1 = a;
    char *c2 = b;
    char temp = *c1;

    *c1 = *c2;
    *c2 = temp;
}

Solution 2

You need to change

 swap=&intSwap;

to

 swap=intSwap;

Same goes for swap=&charSwap; also.

Again, your function signature(s) does not match the function pointer signature.

Your function is

void intSwap(int *a,int *b);

which is of return type void, two input parameters of int *, whereas, your function pointer signature is

void (*swap)(void*,void*);

which takes two void *s. Same for void charSwap function also.

Either yoou have to change the function signature, or you have to use a different function pointer prototype. Otherwise, the behaviour is undefined. [as mentioned in Vlad's answer].

Share:
51,529
sAm
Author by

sAm

Updated on March 25, 2020

Comments

  • sAm
    sAm about 4 years

    I am trying to implement a simple swap function using function pointer but when I assign the function's address to a function pointer:

    `pointersTofunctionB.c:14:6:warning: assignment from incompatible pointer type [enabled by default].

    This is my code:

    #include <stdio.h>
    void intSwap(int *a,int *b);
    void charSwap(char *a,char *b);
    void (*swap)(void*,void*);
    int main(int argc, char const *argv[])
    {
        int a=20,b=15;
        char c='j',d='H';
        swap=&intSwap;// warning here
        swap(&a,&b);
        printf("%d %d\n",a,b);
        swap=&charSwap;// warning here also
        swap(&c,&d);
        printf("%c %c\n",c,d ); 
        return 0;
    }
    
    
    void intSwap(int *a,int *b)
    {
        *a=*a+*b;
        *b=*a-*b;
        *a=*a-*b;
    }
    void charSwap(char *a,char *b)
    {
        char temp;
        temp=*a;
        *a=*b;
        *b=temp;
    }
    

    How can I solve this warning?

  • Michael Burr
    Michael Burr over 9 years
    &intSwap evaluates to the same thing as intSwap by itself. It makes no difference if the ampersand is there or not.
  • Sourav Ghosh
    Sourav Ghosh over 9 years
    @MichaelBurr You're right sir,they both evaluates to same thing. However I thought it's recommended to write as swap=intSwap;. Please correct me I'm wrong.
  • Michael Burr
    Michael Burr over 9 years
    I personally have no strong feelings either way, I'm not sure if others recommend leaving the ampersand off or not.
  • Sourav Ghosh
    Sourav Ghosh over 9 years
    what is this? can you elaborate please?
  • sAm
    sAm over 9 years
    instead doing like how you have mentioned I can simply use the corresponding function name itself. I want to show the the use of function pointer but the modification which you have mentioned wont be sufficient for it.
  • glglgl
    glglgl over 9 years
    using namespace std;? The question is about C, not C++.
  • Michael Beer
    Michael Beer almost 6 years
    You could cast explicitly: swap = (void ( * )(void*, void*))intSwap; Since sizeof(void*) == sizeof(int*) this should be entirely safe and portable.
  • Michael Beer
    Michael Beer almost 6 years
    This would have the benefit of preserving typesafety in case you want to involve intSwap directly somewhere else...