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?
void* is a "pointer to anything". void ** is another level of indirection - "pointer to pointer to anything". Basically, you pass that in when you want to allow the function to return a pointer of any type.
Void functions, also called nonvalue-returning functions, are used just like value-returning functions except void return types do not return a value when the function is executed. The void function accomplishes its task and then returns control to the caller. The void function call is a stand-alone statement.
So, when we define a pointer to pointer. The first pointer is used to store the address of the variable. And the second pointer is used to store the address of the first pointer. That is why they are also known as double pointers.
The int *(a[3]) is the same as plain int *a[3] . The braces are redundant. It is an array of 3 pointers to int and you said you know what it means. The int (*a)[3] is a pointer to an array of 3 int (i.e. a pointer to int[3] type). The braces in this case are important.
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 **
.
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