Can someone help me figure this declaration out?
int *x()(int)
void (*signal(int, void (*fp)(int)))(int)
I can't seem to parse these using methods given here . I know what this means using cdecl.org and also that the 1st one is illegal but I want to figure out how to parse these?
First, some basic rules:
T *a[N]; // a is an array of pointer to T
T (*a)[N]; // a is a pointer to an array of T
T *f(); // f is a function returning a pointer to T
T (*f)(); // f is a pointer to a function returning T
const T *p; // p is a non-const pointer to const T
T const *p; // same as above
T * const p; // p is a const pointer to non-const T
In both declarators and expressions, the []
and ()
operators have higher precedence than the *
operator, so you need to explicitly group it with the identifier when working with pointers to arrays ((*a)[N]
) and pointers to functions ((*f)()
).
When you find a hairy declaration, find the left-most identifier and work your way out, remembering the rules above, and applying them recursively to any function parameters:
signal -- signal
signal( ) -- is a function taking
signal( ) -- parameter unnamed
signal(int, ) -- of type int
signal(int, fp ) -- parameter fp
signal(int, (*fp) ) -- is a pointer
signal(int, (*fp)( )) -- to a function taking
signal(int, (*fp)( )) -- parameter unnamed
signal(int, (*fp)(int)) -- of type int
signal(int, void (*fp)(int)) -- returning void
(*signal(int, void (*fp)(int))) -- returning a pointer
(*signal(int, void (*fp)(int)))( ) -- to a function taking
(*signal(int, void (*fp)(int)))( ) -- parameter unnamed
(*signal(int, void (*fp)(int)))(int) -- of type int
void (*signal(int, void (*fp)(int)))(int); -- returning void
In English, signal
is a function that takes an integer and a pointer to a signal function as parameters and returns a pointer to a handling function.
Occasionally you don't have an identifier (as in a function prototype where only the types are specified), so you have to mentally put in a placeholder (call it λ) and apply the rules to that placeholder:
void (*signal(int λ, void (*fp)(int λ)))(int λ);
When function returns function pointer, return value surrounds the function name and it's arguments. So it helps to start from the center.
But best way to parse function pointer syntax is not have to parse it at all.
Second example can be written using typedef
as:
typedef void funType(int); // Our function type
funType * signal(int i, funType * fp); // Sane version of the function declaration
When you need to use function pointers, always define the function type first with the typedef
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With