放置new运算符的数组周围的括号

6
使用放置new用于数组时,我偶然/错误地得到了以下代码:
#include <new>

struct X{};

int main()
{
    char buf[256];
    std::size_t n = 10;
    X* p = new (buf) (X[n]); // incorrect way, parenthesis by mistake
    //X* p = new (buf) X[n]; // correct way
}
中的第三行是不正确的,尽管它可以编译。不应该有任何圆括号。 clang++产生以下警告

警告:当类型在括号中时,数组不能具有动态大小

然而,gcc6输出:

警告:ISO C++禁止变量长度数组[-Wvla] X* p = new (buf) (X[n]);

警告:非常数数组新长度必须在类型标识符周围没有括号指定[-Wvla] X* p = new (buf) (X[n]);

然后在tree.h:4044处的tree_to_uhwi中崩溃(内部编译器错误[ICE])。内部编译器错误仅在gcc >= 6中出现。

我的问题:标记为“不正确”的行如何被解析/解释,为什么有这些括号是“错误”的?*

*对于ICE,我将填写一个错误报告。

编辑1 我刚意识到ICE /警告与用户定义的类型无关,因此对于int而不是struct X观察到相同的行为。

编辑2 gcc6错误已在此处填写。 ICE不会出现在gcc5或更早版本中(只会出现警告,这是正确的)。

1个回答

3

带括号时,要新建的类型来自于一个类型标识符,在这种情况下是X[n]。这是一个不符合标准行为的可变长度数组。没有括号时,要新建的类型是新类型标识符,一个X的数组。


如果是这种情况,new(buf)(X)和new (buf)X是一样的吗?谢谢。 - user5405790
@KenmanTsang 是的,如果我对标准语言的理解是正确的。 - 1201ProgramAlarm
@Nik-Lz type-idnew-type-id 是语言规范中的术语。您可以在 cppreference.com 上查看它们的含义。 - 1201ProgramAlarm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接