3

I've got a test program to try this:

int main()
{
    int i = 1;
    int* p, q;
    p = &i;
    //q = &i;//q is not pointer
    int* buf[20];//type of element is int*
    return 0;
}

(1) I found q is not pointer, so seems int *p the asterisk is right-associative.

(2) But for int* buf[20], I found buf an array of 20 elements, each typed with int*. So in line 5, seems the asterisk is left-associative.

So what's the exact rule of how * is associated with other parts of an expression, left-associative or right-associative, or apply to other rules?

user207421
  • 305,947
  • 44
  • 307
  • 483
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • `p` and `q` are different variables, they might be different types. But it's impossible to declare an array with the 1st element is a pointer, but the 2nd element is not. – songyuanyao Jul 04 '16 at 02:34
  • I think you're reading too much into this. The first line declares two separate items, the other line declares a single item (an array). – PaulMcKenzie Jul 04 '16 at 02:35
  • Related: [Spiral rule and 'declaration follows usage' for parsing C and C++ declarations](http://stackoverflow.com/questions/3707096/spiral-rule-and-declaration-follows-usage-for-parsing-c-and-c-declarations) – Mark Plotnick Jul 04 '16 at 02:36
  • in `int p, *q, r[3], *s[3], (*t)[3];` -- `p` is `int`, `q` is pointer to `int`, `r` is array of `int`, `s` is array of pointer to `int`, and `t` is pointer to array of `int` – Dmitri Jul 04 '16 at 02:36
  • Your code doesn't contain any `operator*`. – juanchopanza Jul 04 '16 at 06:20
  • The asterisk in the type is not a binary operator; it has no associativity. Associativity only matters in expressions with two or more binary operators. The multiplication operator `*` is left-associative, which means that `a * b * c` is `(a * b) * c`, not `a * (b * c)`. – molbdnilo Jul 04 '16 at 07:45

2 Answers2

9

A declaration consists of a sequence of specifiers followed by a sequence of declarators. Each declarator declares one name. Each specifier applies to each declarator independently. Hence in

int* p, q;

the specifier int applies to both p and q. However, * is not a specifier, and is instead part of the declarator *p, so it only applies to p.

* binds to the entity on its right, but it has lower precedence than [] and (). This precedence rule is the same as that for expressions. & and && (C++ only) have the same precedence as *. In

int* buf[20];

there is one specifier, int, and one declarator, *buf[20], and the [20] binds more tightly, so it's an array of pointers, not a pointer to an array, and the base type is int, so it's an array of pointers to int.

The binding can be altered by parentheses:

int* buf[20]; // array of pointers
int (*buf)[20]; // pointer to array
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
0

This is working right

int* p, q;

Since it doest matter it was int* p or int *p, the issue here is that q is after the comma which will need another pointer * if you want it to be a pointer too.

This line:

int* buf[20];//type of element is int*

Also does what is supposed to do, declare array of int pointers, which is the same as int *buf[20]

MoustafaS
  • 1,991
  • 11
  • 20