19

This question follows this other question about C declarations. Reading the answer to this question, I read about the spiral rule and I also understood what "declaration follows usage" means.

Ok so far. But then I read this declaration:

char *(*(*a[N])())(); 

and I was wondering how to parse it with the "declaration follows usage" 'rule'. Especially for the array part.

What I read is:

(*(*a[N])()) 

is a function () returning a char *, then, dereferencing the following

(*a[N])() // 1

is this 'function returning a char*', and so 1 is a 'pointer to a function returning char *' then I would say 'when (*a[N]) is called, it is [previous declaration]'. At this point we have (*a[N]) is a function returning a pointer to a function returning char *.

But then I don't know how to apply this rule to distinguish between the 'pointer to array' and 'array of pointer'.

Can someone clarify this?

Other question: what are the rules of "precedence" in such declarations, between & (in C++), *, and []? [maybe "precedence" is not the correct term]


To check if I understood the 'spiral rule' correctly, I also parse this expression below; please tell me if I am wrong.

       +-----------+
       | +------+  |
       | | +-+  |  |
       | | ^ |  |  |
char* (*(* a[N])())(); 
    ^  ^ ^   ^  ^  ^
    |  | |   |  |  |
    |  | +---+  |  |
    |  +--------+  |
    +--------------+

For me it is easier (loop by loop):

  • a is an array of N ...
  • pointer to function returning ...
  • pointer to function returning ...
  • char *

But I am maybe missing something which in that case let me obtain the correct answer but that could be wrong in another more complicated case.

Community
  • 1
  • 1
Cedric H.
  • 7,980
  • 10
  • 55
  • 82
  • @Vality: If you're going to drop the C++ tag, you need to drop the mention of `&` in C++ too. – Jonathan Leffler Dec 31 '15 at 22:36
  • @JonathanLeffler Good point, Normally I would say this needs to be split into two questions, but its such an old question I am reluctant to do so. – Vality Jan 01 '16 at 02:21
  • @Vality How come the question suddenly got so much attention? (I was notified for the 'nice question' badge). – Cedric H. Jan 01 '16 at 10:20
  • @CedricH. I suspect it is because the in-progress vote to flag http://stackoverflow.com/questions/34548762/ as a duplicate of this. – Vality Jan 01 '16 at 10:42

1 Answers1

16

You just have to build it up in steps.

char *X();  // X =~ (*(*a[N])())

Function returning char*

char *(*Y())();  // Y =~ (*a[N])

Function returning pointer to function returning char*.

In a declaration, just as in an expression (declaration follow usage), postfix [] has a higher precedence that unary * so *a[N] is equivalent to *(a[N]), not (*a)[N].

char *(*(*Z)())();  // Z =~ a[N]

Pointer to function returning pointer to function returning char*.

char *(*(*a[N])())();

Array of N pointers to functions returning a pointer to function returning char*.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656