为什么new int(*)[3]出错?

M.M*_*M.M 8 c++ syntax-error new-operator

typedef int (*A)[3];

int (**p)[3] = new A;              // OK
int (**q)[3] = new (int(*)[3]);    // OK
int (**r)[3] = new int (*)[3];     // error
Run Code Online (Sandbox Code Playgroud)

GCC的错误是error: expected primary-expression before ')' token.为什么这个表达式需要额外的括号?

Ale*_*exD 10

该标准将new-type-id定义为新声明的最长序列.还有一个注释,它说明了类似的情况(尽管它分配了指向函数的指针):

5.3.4新[expr.new]

....

new-type-id:
    type-specifier-seq new-declarator opt

new-declarator:
    ptr-operator new-declarator opt
     noptr-new-declarator

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

....

新型-ID在一个新的表达是可能的最长序列的新声明符.[ 注意:这防止了说明符运营商之间的模糊&,&&,*,和[]和它们的表达对应.-  尾注 ] [ 示例:

new int * i; // syntax error: parsed as (new int*) i, not as (new int)*i
Run Code Online (Sandbox Code Playgroud)

*是指针说明符,而不是乘法运算.-  结束例子 ]

[ :在括号新型-ID一个的新的表达可以有意想不到的效果.[ 例如:

new int(*[10])(); // error
Run Code Online (Sandbox Code Playgroud)

因为绑定是错误的

(new int) (*[10])(); // error
Run Code Online (Sandbox Code Playgroud)

相反,new运算符的显式括号版本可用于创建复合类型的对象(3.9.2):

new (int (*[10])());
Run Code Online (Sandbox Code Playgroud)

为函数分配一个10个指针的数组(不带参数并返回int. -  结束示例 ] -  结束注释 ]