[comp.lang.c] can you 'splain this to me?: Reading complex C declarations

bobg+@andrew.cmu.edu (Robert Steven Glickstein) (07/17/87)

(The following was posted by me to a local bboard at CMU during the academic
year, to help others in one of my classes understand C declarations.  Forgive
me if it's a little didactic for the high-caliber C hackers here.)

Reading complex C declarations isn't so hard, as long as you know the
"right-left" rule.  Consider the following expression:

char  *(*(*foobar[])())[]  ; 


Basically, the "right-left" rule works in the following way:


1) Start at the identifier in question.

2) Look for clues on the right (a clue is, for example, a pair of square
brackets [], indicating an array of something, or round brackets (),
indicating a function returning something).  Stop if you hit a parenthesis.

3) Look for clues on the left (the only clue you'll ever find on the left is
*, indicating a pointer to something).  Stop if you hit a parenthesis.

4) Go back to the right, one level further out than your last pass.

5) Go back to the left, one level further out.

6) etc....

... tumbolia ... 

N) Finally, look at the type declarator to the far left.


Gee, I haven't stated the rule very clearly, it seems, but it should become
clear when applied to the above example.


char  *(*(*foobar[])())[]  ; 


1) Start at the identifier ("foobar").

2) Look for clues on the right of foobar.  We find square brackets. Result:
"foobar is an array... "


char  *(*(*XXX)())[]  ;	/* XXX replaces the part of the expression
already parsed */ 


3) Look to the left.  Find a *.  XXX is a pointer.  Result: "foobar is an
array of pointers... "


char  *(*(XXX)())[]  ; 


4) Go back to the right.  Hit a parenthesis.  No change.

5) Go back to the left, hit a parenthesis.  No change.


char  *(*XXX())[]  ; 


6) Go back to the right (now out a level).  Find ().  XXX is a function.
Result: "foobar is an array of pointers to functions... "


char  *(*XXX)[]  ; 


7) Go to the left, find a *.  XXX is a pointer.  Result: "foobar is an array
of pointers to functions returning pointers... "


char  *(XXX)[]  ; 


8) Go back to the right, hit a parenthesis.  No change.

9) Go back to the left, hit a parenthesis.  No change.


char  *XXX[]  ; 


10) Go to the right.  Find [].  XXX is an array.  Result: "foobar is an array
of pointers to functions returning pointers to arrays... "


char  *XXX  ; 


11) Go to the left.  Find  *.  XXX is a pointer.  Result: "foobar is an array
of pointers to functions returning pointers to arrays of pointers... "


char  XXX  ; 


N=12) Finally, look to the type declarator on the far left ("char").  XXX is
a character.  Therefore, "foobar is an array of pointers to functions
returning pointers to arrays of pointers to characters. "


char  *(*(*foobar[])())[]  ; /* See? */


Parsing the following should be simple and mechanical:


int  *(**hello())[]  ; 


Hello is a function returning a pointer to a pointer to an array of pointers
to integers.


-Bob Glickstein()


[Glickstein is a function returning a Bob].


-Bob Glickstein                 |
-Information Technology Center  | We begin bombing in 5 minutes.
-Carnegie Mellon University     |   --Ronald Reagan
-Pittsburgh, PA                 |

    bobg+@andrew.cmu.edu