#include <stdio.h>
typedef int (*func_t)(int);
int foo(int x) {
return x * 2;
}
int main() {
const func_t ptr = foo; // Works
//const func_t *ptr = &foo; // Fails: why?
printf("%d\n", ptr(5)); // Outputs 10
}
Issue:
The line const func_t ptr = foo;
works fine.
However, uncommenting const func_t *ptr = &foo;
results in a compilation error
error: invalid conversion from 'int (*)(int)' to 'const func_t*' {aka 'int (* const)(int)'}
Why does const func_t *ptr = &foo;
fail, and how can I fix it?
This is one of the reasons why hiding pointers behind typedef
isn't a good idea.
const func_t ptr
makes the function pointer "const". That is, it is equivalent to int (* const func_t)(int);
.
Functions, whenever used in expressions, "decay" into a pointer to that function. That's why ptr = foo;
works, foo
decays into an int (*)(int)
. However, just like when dealing with arrays, decay does not happen in case of &
. So &foo
gives a pointer to a function too.
And you cannot assign an int (*)(int)
to a pointer-to-pointer to function and const
has nothing to do with that - it's simply the wrong number of redirections.
You could however do this:
const func_t ptr1 = foo;
const func_t* ptr2 = &ptr1;
ptr2
is int (*const *)(int)
and that's what you get if you take &ptr1
.
Best practice here is to get rid of the hidden pointer inside the typedef
in the first place, since it is obviously quite confusing:
typedef int func_t (int);
...
func_t* const ptr1 = foo;