Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The rule is correct. However, one should be very careful in applying it.</p> <p>I suggest to apply it in a more formal way for C99+ declarations.</p> <p>The most important thing here is to recognize the following recursive structure of all declarations (<code>const</code>, <code>volatile</code>, <code>static</code>, <code>extern</code>, <code>inline</code>, <code>struct</code>, <code>union</code>, <code>typedef</code> are removed from the picture for simplicity but can be added back easily):</p> <pre><code>base-type [derived-part1: *'s] [object] [derived-part2: []'s or ()] </code></pre> <p>Yep, that's it, four parts.</p> <pre><code>where base-type is one of the following (I'm using a bit compressed notation): void [signed/unsigned] char [signed/unsigned] short [int] signed/unsigned [int] [signed/unsigned] long [long] [int] float [long] double etc object is an identifier OR ([derived-part1: *'s] [object] [derived-part2: []'s or ()]) * is *, denotes a reference/pointer and can be repeated [] in derived-part2 denotes bracketed array dimensions and can be repeated () in derived-part2 denotes parenthesized function parameters delimited with ,'s [] elsewhere denotes an optional part () elsewhere denotes parentheses </code></pre> <p>Once you've got all 4 parts parsed,</p> <p>&nbsp;&nbsp;[<code>object</code>] is [<code>derived-part2</code> (containing/returning)] [<code>derived-part2</code> (pointer to)] <code>base-type</code> <sup>1</sup>.</p> <p>If there's recursion, you find your <code>object</code> (if there's any) at the bottom of the recursion stack, it'll be the inner-most one and you'll get the full declaration by going back up and collecting and combining derived parts at each level of recursion.</p> <p>While parsing you may move <code>[object]</code> to after <code>[derived-part2]</code> (if any). This will give you a linearized, easy to understand, declaration (see <sup>1</sup> above).</p> <p>Thus, in</p> <pre><code>char* (**(*foo[3][5])(void))[7][9]; </code></pre> <p>you get:</p> <ol> <li><code>base-type</code> = <code>char</code></li> <li>level 1: <code>derived-part1</code> = <code>*</code>, <code>object</code> = <code>(**(*foo[3][5])(void))</code>, <code>derived-part2</code> = <code>[7][9]</code></li> <li>level 2: <code>derived-part1</code> = <code>**</code>, <code>object</code> = <code>(*foo[3][5])</code>, <code>derived-part2</code> = <code>(void)</code></li> <li>level 3: <code>derived-part1</code> = <code>*</code>, <code>object</code> = <code>foo</code>, <code>derived-part2</code> = <code>[3][5]</code></li> </ol> <p>From there:</p> <ol> <li>level 3: <code>*</code> <code>[3][5]</code> <code>foo</code></li> <li>level 2: <code>**</code> <code>(void)</code> <code>*</code> <code>[3][5]</code> <code>foo</code></li> <li>level 1: <code>*</code> <code>[7][9]</code> <code>**</code> <code>(void)</code> <code>*</code> <code>[3][5]</code> <code>foo</code></li> <li>finally, <code>char</code> <code>*</code> <code>[7][9]</code> <code>**</code> <code>(void)</code> <code>*</code> <code>[3][5]</code> <code>foo</code></li> </ol> <p>Now, reading right to left:</p> <p><code>foo</code> is an array of 3 arrays of 5 pointers to a function (taking no params) returning a pointer to a pointer to an array of 7 arrays of 9 pointers to a char.</p> <p>You could reverse the array dimensions in every <code>derived-part2</code> in the process as well.</p> <p>That's your spiral rule.</p> <p>And it's easy to see the spiral. You dive into the ever more deeply nested <code>[object]</code> from the left and then resurface on the right only to note that on the upper level there's another pair of left and right and so on.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload