void (*func)(int(*[ ])());
-
See http://stackoverflow.com/questions/1448849/how-to-understand-complicated-function-declarations – pmg Nov 06 '09 at 13:10
6 Answers
The general procedure for reading hairy declarators is to find the leftmost identifier and work your way out, remembering that []
and ()
bind before *
(i.e., *a[]
is an array of pointer, not a pointer to an array). This case is made a little more difficult by the lack of an identifier in the parameter list, but again, []
binds before *
, so we know that *[]
indicates an array of poitners.
So, given
void (*func)(int(*[ ])());
we break it down as follows:
func -- func
*func -- is a pointer
(*func)( ) -- to a function taking
(*func)( [ ] ) -- an array
(*func)( *[ ] ) -- of pointers
(*func)( (*[ ])()) -- to functions taking
-- an unspecified number of parameters
(*func)(int(*[ ])()) -- returning int
void (*func)(int(*[ ])()); -- and returning void
What this would look like in practice would be something like the following:
/**
* Define the functions that will be part of the function array
*/
int foo() { int i; ...; return i; }
int bar() { int j; ...; return j; }
int baz() { int k; ...; return k; }
/**
* Define a function that takes the array of pointers to functions
*/
void blurga(int (*fa[])())
{
int i;
int x;
for (i = 0; fa[i] != NULL; i++)
{
x = fa[i](); /* or x = (*fa[i])(); */
...
}
}
...
/**
* Declare and initialize an array of pointers to functions returning int
*/
int (*funcArray[])() = {foo, bar, baz, NULL};
/**
* Declare our function pointer
*/
void (*func)(int(*[ ])());
/**
* Assign the function pointer
*/
func = blurga;
/**
* Call the function "blurga" through the function pointer "func"
*/
func(funcArray); /* or (*func)(funcArray); */

- 119,563
- 19
- 122
- 198
-
1+1 for good enough try to explain how to read such expressions and example. – Roman Nikitchenko Nov 06 '09 at 15:47
It's not a statement, it's a declaration.
It declares func
as a pointer to a function returning void and taking a single argument of type int (*[])()
, which itself is a pointer to a pointer to a function returning int and taking a fixed but unspecified number of arguments.
cdecl output for ye of little faith:
cdecl> explain void (*f)(int(*[ ])());
declare f as pointer to function (array of pointer to function returning int) returning void

- 233,326
- 40
- 323
- 462
-
"fixed but unspecified number of arguments" - the question is also tagged C++, in which case that second function type takes precisely zero arguments. – Steve Jessop Nov 06 '09 at 13:26
-
3The C++ tag was added by someone other than the original poster, after I'd answered. A move too-clever-by-half, by my book. – caf Nov 06 '09 at 13:27
-
Gosh, that is sneaky. It's never clear when someone says "C/C++" whether they've said it because they think the answer is the same for both languages, because they think the answers is different between the two... – Steve Jessop Nov 06 '09 at 13:51
-
+1, i just wanna explain why you say "pointer to pointer" and cdecl says "array of pointer": this is because in functions, parameters declared as arrays become pointers. Just so no-one says "hey, you have a typo" :) – Johannes Schaub - litb Nov 06 '09 at 15:37
Yes:
$ cdecl explain void (* x)(int (*[])()); declare x as pointer to function (array of pointer to function returning int) returning void
-
-
-
It shows you cheated, lulz (btw it's a good cheat, cdecl is nice xD) – Johannes Schaub - litb Nov 06 '09 at 16:23
void (*func)(blah);
is a pointer to a function taking blah
as an argument, where blah
itself is int(*[ ])()
is an array of function pointers.

- 5,411
- 22
- 38
Here's a guide on reading C declarations:
http://www.ericgiguere.com/articles/reading-c-declarations.html

- 11,167
- 7
- 37
- 46
Geordi
is a C++ bot, allowing to train this:
<litb> geordi: {} void (*func)(int(*[ ])());
<litb> geordi: -r << ETYPE_DESC(func)
<geordi> lvalue pointer to a function taking a pointer to a pointer to a nullary function
returning an integer and returning nothing
It can do many useful things, like showing all parameter-declarations (this, in fact, is just matching raw C++
grammar rule names):
<litb> geordi: show parameter-declarations
<geordi> `int(*[ ])()`.
Let's do it in the opposite direction:
<litb> geordi: {} int func;
<litb> geordi: make func a pointer to function returning void and taking array of pointer to
functions returning int
<litb> geordi: show
<geordi> {} void (* func)(int(*[])());
It executes anything you give to it, if you ask it. If you are trained but just forgot some of the scary parentheses rules, you may also mix C++ and geordi-style type descriptions:
<litb> geordi: make func a (function returning void and taking (int(*)()) []) *
<geordi> {} void (* func)(int(*[])());
Have fun!

- 496,577
- 130
- 894
- 1,212