Close, but no banana.
Watch carefully, because the difference is a subtle one.
It is clear that a function
- or a pointer to function - is involved. We
don't actually care, at this stage, what the parameter list is,
so let's replace the whole list with X, giving:
void (*signal(X))(int);
We can now see that signal is a function,
NOT a pointer to function. This
function /returns/ a pointer to function.
If this were a declaration of a
pointer to a function type, it would be:
void (*signal)(int);
or perhaps:
void (*signal)(X, int);
but certainly not:
void (*signal(X))(int);
In case you don't see it,
let's build up a declaration of our own. Let's
write a function prototype for a function, foo (what else?), that both
takes and returns a pointer to a function taking
char and returning double;
our function will also take a struct tm (as its first param), for good
measure. We could cheat and do this:
typedef double fp(char);
fp *foo(struct tm, fp *);
But let's avoid typedef for once. So how do we do it?
We start off with foo, of course:
foo
foo is a function, so let's add the function syntax:
foo()
What does foo take? A pointer to a function taking char and returning
double, and also a struct tm:
foo(struct tm, double (*funcptr)(char))
Now for the return value.
We need to return a pointer to a function, not a
pointer to double, so we can't say:
double *foo.....(char);
Instead, we need parens:
double (*foo(struct tm, double (*funcptr)(char)))(char);
and we're done. Compare signal:
void (*signal( int sig, void (*function)(int))) (int);
Conclusion: signal is indeed a function prototype, not a pointer to a
function type, QED.
But I don't blame you for getting that one wrong.