Search code examples
cpointerscastingfunction-pointerstypedef

How to declare a type for function pointer variable in C without using "typedef"?


I have a function called add which adds two integers as shown below:

int add(int a, int b){
    return a + b;
}

and I wanted to create a pointer to my function named a and call my function using it

printf("The sum of 45, 23: %d\n", a(45, 23));

I did it by creating a type for my function with typedef

typedef int (*Aptr) (int, int);

Aptr a = &add;

printf("The sum of 45, 23: %d\n", a(45, 23));
The sum of 45, 23: 68

But when I tried to use the type in the typedef statement with my variable, it causes an error and I tried removing the replacement name too but it is throwing an error. If the purpose of typedef is just creating a new name for existing data type why is this not working?

int (*Aptr) (int, int) a = &add;
int (*) (int, int) a = &add;

For both cases:

[Error] 'a' undeclared (first use in this function)
[Note] each undeclared identifier is reported only once for each function it appears in
[Warning] implicit declaration of function 'a' [-Wimplicit-function-declaration]

is there any other way to state the data type of a function to function pointer?


Solution

  • I did it by creating a type for my function with typedef

    Nitpick: you did it by using typedef to declare an alias for the function's type. This does not create a type.

    If the purpose of typedef is just creating a new name for existing data type why is this not working?

    Because you're doing it wrong.

    Adding typedef to a valid declaration says that instead of declaring that the specified identifier designates an object or function of the specified type, that identifier will serve as an alias for the type. If you instead want to declare an actual object or function, then all you need to do is remove the typedef:

    int (*Aptr) (int, int);
    

    You can, of course, choose a different identifier:

    int (*a) (int, int);
    

    Each of those declares a pointer to a function that has two parameters of type int and returns an int.

    This variation:

    int (*Aptr) (int, int); a = &add;
    

    contains both a declaration (int (*Aptr) (int, int);) and a statement (a = &add;). The former is a perfectly valid declaration of Aptr as a function pointer, as already discussed. The part after the first semicolon is separate, an attempt to assign a value to undeclared variable a.

    This variation:

    int (*) (int, int); a = &add;
    

    is similar, but a bit further off. int (*) (int, int) is a valid type name, and it can be used in that form in a typecast, but to declare a variable of that type, you need to put the variable name at the appropriate point inside. The form you want is:

    int (*a) (int, int) = &add;
    

    or alternatively,

    int (*a) (int, int);
    a = &add;
    

    or either of the above without the &, which is unneeded (but not wrong) when add identifies a function.