Reputation: 10499
I am having difficulty trying to understand what the following declaration means. Is this declaration standard?
double* (*p[3]) (void* (*)());
Can anyone help me to understand the meaning of this declaration?
Upvotes: 8
Views: 1409
Reputation: 782
"There is a technique known as the ``Clockwise/Spiral Rule'' which enables any C programmer to parse in their head any C declaration!"
Clockwise Spiral Rule - http://c-faq.com/decl/spiral.anderson.html
Upvotes: 0
Reputation: 123458
Rule for reading hairy declarations: find the leftmost identifier and work outward, remembering that ()
and []
bind before *
, so T *a[N]
is an array of pointers to T
, T (*a)[N]
is a pointer to an array of T
, T *f()
is a function returning a pointer to T
, and T (*f)()
is a pointer to a function returning T. Since a function prototype may omit parameter names, you may see things like T *[N]
or T (*)()
. The meaning is mostly the same1, just pretend that there's an identifier of 0 length.
Thus,
p -- p
p[3] -- is a 3-element array
*p[3] -- of pointers
(*p[3]) ( ) -- to functions
(*p[3]) ( (*)()) -- taking a pointer to a function
(*p[3]) ( * (*)()) -- returning a pointer
(*p[3]) (void* (*)()) -- to void
* (*p[3]) (void* (*)()) -- returning a pointer
double* (*p[3]) (void* (*)()); -- to double
The important thing to take away here is that you are declaring p
as an array of ...
, not a function returning ...
.
What would such a beast look like in practice? Well, first, you need three functions to point to. Each of these functions takes a single parameter, which is a pointer to a function returning a pointer to void:
double *foo(void *(*)());
double *bar(void *(*)());
double *bletch(void *(*)());
double *(*p[3]) (void *(*)()) = {foo, bar, bletch};
Each of foo
, bar
, and bletch
would call the function passed to it and somehow return a pointer to double
.
You would also want to define one or more functions that satisfy the parameter type for each of foo
, bar
, and bletch
:
void *blurga() {...}
so if you called foo
directly, you'd call it like
double *pv;
...
pv = foo(blurga);
So we could imagine a call like
double *pv = (*p[0])(blurga);
T a[]
and T a[N]
are identical to T *a
; in all three cases, a
is a pointer to T
, not an array of T
. Note that this is only true in a function parameter declaration. Thus, T *[]
will be identical to T **
.
Upvotes: 10
Reputation: 8928
Your p
is an array of 3 pointers to a function returning a double
pointer, and taking as argument a pointer to another function that returns a void
pointer and that takes no arguments.
But, don't use this syntax, try using typedef instead.
Upvotes: 2
Reputation: 24895
It is array (of size 3) of function pointers which returns pointer to double and take another function pointer as argument.
Type of function whose pointer can be stored in the array: double *(func)(void* (*)())
Type of function whose pointer can be passed as argument to func: void *(func1)(void)
Upvotes: 1
Reputation: 272487
Just use http://cdecl.org:
declare p as array 3 of pointer to function (pointer to function returning pointer to void) returning pointer to double
For more info, see this MSDN article: Interpreting more complex declarators.
But typedefs would help:
typedef void *(*foo)(); // foo is a function-pointer type
typedef double *(*bar)(foo); // bar is also a function-pointer type
bar p[3];
(Obviously, use appropriate names in place of foo
and bar
!)
Upvotes: 10