Iwata Kurosawa
Iwata Kurosawa

Reputation: 73

Function Pointers Casting in C

Why do i need to remove the function pointer casting to use the function as shown below ?

This Compiles:

#include <stdio.h>

int print_int(int i){
    printf("%d", i);
    return i;
}
typedef int (*print_int_func) (int);

int main(){
    void** p = malloc(1*sizeof(print_int_func*));
    p[0] = (print_int_func*)print_int;

    ((print_int_func)p[0])(2); // This Compiles
    ((print_int_func*)p[0])(2); // This does NOT
    
    return 0;
}

Upvotes: 0

Views: 80

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 224310

The declaration typedef int (*print_int_func) (int); declares print_int_func to be a pointer to a specific type of function. So (print_int_func)p[0] casts p[0] to such a pointer to a function, but (print_int_func*)p[0] casts p[0] to a pointer to a pointer to a function. Thus, the result is a pointer to an object (that object being a pointer to a function). Since it is an object, not a function (or pointer to a function), it cannot be called like a function.

Additionally, avoid using void * for pointers to functions. void * is a pointer to an object, and the C standard does not define conversions between pointers to objects and pointers to functions. To create a “generic” pointer to a function, simply choose any function type and use a pointer to that type:

  • Convert to the chosen type when storing the pointer.
  • Convert to the actual function type when calling the function type.

For example, you can declare an arbitrary type:

typedef void (*CommonFunctionPointer)(void);

and make an array of them:

CommonFunctionPointer *p = malloc(N * sizeof *p);,

and then you can store any function pointer in the array:

p[i] = (CommonFunctionPointer) print_int;

and use a pointer from the array by casting it back to its correct type:

((int (*)(int)) p[i])(2);.

Upvotes: 1

Related Questions