4

Wikipedia claims that the [] operator precedes the * operator in evaluation.

Then, why does the following statement:

char *a[3];

declare an array of 3 character pointers, rather than a pointer to an array of 3 characters as per the operator precedence?

  • Similar: http://stackoverflow.com/questions/859634/c-pointer-to-array-array-of-pointers-disambiguation Specifically see the answer regarding `cdecl` –  Jan 22 '11 at 22:02

3 Answers3

7

Because, as Wikipedia says, [] has higher precedence than *?

Processing the declaration, the a[3] is processed as 'array of 3' before you process the *.

To declare a pointer to an array of three characters, you have to use parentheses to override the default precedence:

char (*a)[3];

Now the parentheses take precedence over the array.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    But don't declarations have separate interpretation rules as claimed in other answers? –  Jan 22 '11 at 19:32
  • 1
    @crypto, the whole point of declaration syntax in C is that "declaration mimicks use". – AProgrammer Jan 22 '11 at 20:15
  • @crypto: No, not really. As @AProgrammer says, the design of the C declaration system is such that declaration mimics use. So, `a[0]` is a `char *`, and `*a[0]` is a `char`. – Jonathan Leffler Jan 22 '11 at 21:28
  • 1
    @crypto: See my answer below. Yes, there are different production rules for declarations, but they follow the same precedence rules as expressions. – John Bode Jan 22 '11 at 21:46
2

Here's the grammar for a declarator as taken from the standard (§ 6.7.5):

declarator:
    pointeropt direct-declarator

direct-declarator:
    identifier
    ( declarator )
    direct-declarator [ type-qualifier-listopt assignment-expressionopt ]
    direct-declarator [ static type-qualifier-listopt assignment-expression ]
    direct-declarator [ type-qualifier-list static assignment-expression ]
    direct-declarator [ type-qualifier-listopt * ]
    direct-declarator ( parameter-type-list )
    direct-declarator ( identifier-listopt )

pointer:
    * type-qualifier-listopt
    * type-qualifier-listopt pointer

type-qualifier-list:
    type-qualifier
    type-qualifier-list type-qualifier

parameter-type-list:
    parameter-list
    parameter-list , ...

parameter-list:
    parameter-declaration
    parameter-list , parameter-declaration

parameter-declaration:
    declaration-specifiers declarator
    declaration-specifiers abstract-declaratoropt

identifier-list:
    identifier
    identifier-list , identifier

As you can see, both [] and () bind to the declarator before *. Take the declaration

int *a[N];

The declarator is *a[N], which fits the pointeropt direct-declarator pattern above, and is thus parsed as *(a[N]), so a is an N-element array of pointer.

To sum up:

T *a[N]      -- declares an N-element array of pointer to T
T (*a)[N]    -- declares a pointer to an N-element array of T
T *f()       -- declares a function returning pointer to T
T (*f)()     -- declares a pointer to a function returning T  
John Bode
  • 119,563
  • 19
  • 122
  • 198
0

I'm confused about the question - the interpretation of the declaration matches the operator precedence. If you want a pointer to an an array you have to use parens to 'bind the * to the indentifier' before the [] binding.

char (*a)[3];
Michael Burr
  • 333,147
  • 50
  • 533
  • 760