0

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

5
  • If you're assigning to void**, you need to use malloc(1 * sizeof(void*)). The argument to sizeof is always the destination type with one less *. Commented Dec 11, 2020 at 22:44
  • @Barmar I am trying to store functions inside a void pointer array. Currently it works. However I am trying to understand why the pointer declaration is such. Commented Dec 11, 2020 at 22:48
  • See stackoverflow.com/questions/3941793/… there's no guarantee that a void* can hold a function pointer. Commented Dec 11, 2020 at 22:50
  • In general you don't dereference function pointers. Commented Dec 11, 2020 at 22:50
  • @Barmar: They should not be using void * in the first place; function pointers are different from object pointers, and void * is not a generic type for function pointers. Additionally, its preferable to use the actual identifier being assigned, with an *, for the sizeof, rather than repeating the type: AnyType *p = malloc(NumberOf * sizeof *p);. Commented Dec 11, 2020 at 22:51

1 Answer 1

1

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);.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank You ! So (print_int_func)p[0] casts p[0] into a function so it can be called.
In relation to object vs function pointers, what is the rationale behind it ? Is it because C does not give any solid guarantees on it's integrity during usage ?
@IwataKurosawa: Specifically, it casts p[0] to a pointer to a function. The function call operator (parentheses after an expression) only calls pointers to functions. When you write a function call using a function name, like sin(x), the function is automatically converted to a pointer.
(This is true even if the function is created by dereferencing a pointer. If you have a q that points to a function and write (*q)(x), *q is a function, but it is automatically converted to a pointer to the function. And then you can apply * again. (**q)(x) calls the same function. So does (******q)(x).)
@IwataKurosawa: Object pointers and function pointers are different because in some computers, their addresses were managed differently, and the C standard wanted to allow C to be used on a wide variety of computers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.