10
typedef int (*A)[3];

int (**p)[3] = new A;              // OK
int (**q)[3] = new (int(*)[3]);    // OK
int (**r)[3] = new int (*)[3];     // error

The error from GCC is error: expected primary-expression before ')' token . Why are the extra parentheses required in this expression?

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Related (but not duplicate): http://stackoverflow.com/q/16634713/1505939 – M.M Sep 25 '14 at 02:05
  • 1
    Because a *new-type-id* may not contain parentheses. But that's of course not a satisfying answer. – dyp Sep 25 '14 at 02:07
  • Maybe this has to do with disambiguation; e.g. `new int()` could be interpreted as trying to allocate a function `int (void)` – dyp Sep 25 '14 at 02:11
  • Why would you want to dynamically allocate an array pointer anyhow? Seems like a hint that the underlying program design is needlessly complex. – Lundin Sep 25 '14 at 06:30

1 Answers1

13

The standard defines new-type-id as the longest sequence of new-declarators. There is also a note, which illustrates a similar situation (although it allocates pointers to functions):

5.3.4 New [expr.new]

....

new-type-id:
    type-specifier-seq new-declaratoropt

new-declarator:
    ptr-operator new-declaratoropt
    noptr-new-declarator

noptr-new-declarator:
    [ expression ]  attribute-specifier-seqopt
    noptr-new-declarator  [ constant-expression ]  attribute-specifier-seq opt

....

The new-type-id in a new-expression is the longest possible sequence of new-declarators. [ Note: this prevents ambiguities between the declarator operators &, &&, *, and [] and their expression counterparts. — end note ] [ Example:

new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i

The * is the pointer declarator and not the multiplication operator. — end example ]

[ Note: parentheses in a new-type-id of a new-expression can have surprising effects. [ Example:

new int(*[10])(); // error

is ill-formed because the binding is

(new int) (*[10])(); // error

Instead, the explicitly parenthesized version of the new operator can be used to create objects of compound types (3.9.2):

new (int (*[10])());

allocates an array of 10 pointers to functions (taking no argument and returning int. — end example ] — end note ]

AlexD
  • 32,156
  • 3
  • 71
  • 65
  • @M.M As usual, with the standard it is a bit difficult. I added some grammar constructions, but they are not complete. E.g. things like _expression_ or _attribute-specifier-seq_ are not defined here. – AlexD Sep 26 '14 at 01:18
  • @AlexD *expression* would be too complicated, and *attribute-specifier-seq* is irrelevant. IMHO, the interesting part is that the *new-expression* can be either contain a (completely) parenthesized *type-id* or a(n unparenthesized) *new-type-id*, where the *new-type-id* may (as far as I can see) not contain any parentheses. – dyp Sep 26 '14 at 19:25
  • @dyp As far as I understand, _new_type_id_ may contain _expression_, which may contain parentheses, e.g. `new int [(3)]`. BTW, thanks for editing of the first post! – AlexD Sep 26 '14 at 20:14