How do I interpret complex declarations like:
int * (* (*fp1) (int) ) [10]; ---> declaration 1
int *( *( *[5])())(); --------> declaration 2
For solving these complicated declarations, the rule you need to keep in mind is that the precedence of function-call operator () and array subscript operator [] is higher than dereference operator *. Obviously, parenthesis ( ) can be used to override these precedences.
Now, work out your declaration from the middle, which means from the identifier name.
int * (* (*fp1) (int) ) [10]; --->declaration 1
Based on the precedences rule mentioned above, you can easily understand it by breaking down the declaration as
fp1 * (int) * [10] * int
and read it directly from left-to-right in English as "fp1 is a pointer to a function accepting an int & returning a pointer to an array [10] of pointers to int". Note that the declaration is broken this way only to help understand it manually. The compiler need NOT parse it this way.
Similarly,
int *( *( *[5])())(); -------->declaration 2
is broken as
[5] * () * () * int
So, it declares "an array [5] of type pointers to function () which returns a pointer to a function () which in turn returns a pointer to int".
You can use cdecl*
:
cdecl> explain int *( *( *a[5])())();
declare a as array 5 of pointer to function
returning pointer to function returning pointer to int
cdecl> explain int * (* (*fp1) (int) ) [10];
declare fp1 as pointer to function (int) returning
pointer to array 10 of pointer to int
*
Linked is a website that uses this command line tool in the backend.