Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spiral rule and 'declaration follows usage' for parsing C and C++ declarations

Tags:

c++

c

declaration

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.

like image 508
Cedric H. Avatar asked Sep 14 '10 08:09

Cedric H.


1 Answers

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*.

like image 135
CB Bailey Avatar answered Sep 29 '22 05:09

CB Bailey