C has some magic built-in involving the equivalence of pointers and functions, and the equivalence of pointers and arrays. For that reason, you can sometimes "get away" with not spelling out the full dereference of a pointer when it points to an array or a function.
However, I'd like to point out (ahem, see what I did there?) that one of the design goals of C type declarations is that the declaration of an object and the use of that object are the same.
For example:
int *p; // p is a pointer to int
Now, how do I get an int
?
int y = /* wait for it ... */ *p;
Similarly,
float *****p[2];
float y = *****p[0]; // or [1]
So, if you have this declaration:
int (*ptr)() = a_function;
Then let's ask the question, "How can you get an int?" Which is to say, how can you invoke the pointer-to-function-taking-no-args-returning-int? The answer is to replicate what you have already declared:
int y = (*ptr)();
Yes, you could say "ptr is a pointer, and there is a magic equivalence between functions and pointer-to-functions, to p()
will work". But don't. Because right now, you aren't confident enough to do that. So just trust that for whatever C declaration, if you want to get the type on the very left, all you need to do is use the *
's and []
's and ()
's on the right, and you'll get there.