【问题标题】:Parenthesis around placement new operator for arrays数组的放置新运算符周围的括号
【发布时间】:2017-02-01 23:03:51
【问题描述】:

玩弄新的数组放置,我(偶然/错误地)想到了以下代码:

#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
}

main 中的第三行不正确,尽管它可以编译。不应该有任何括号。 clang++ spits out

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

当 gcc6 输出时

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

警告:非常量数组的新长度必须在 type-id [-Wvla] 周围不带括号的情况下指定 X* p = new (buf) (X[n]);

然后crashes with an internal compiler error (ICE)tree_to_uhwi,在 tree.h:4044。内部编译器错误只出现在 gcc >= 6 中。

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

*对于 ICE,无论如何我都会填写一个错误。

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

EDIT 2 gcc6 错误填充here。 ICE在gcc5或更早的版本中没有出现(只有警告出现,是正确的)。

【问题讨论】:

    标签: c++ gcc clang placement-new internal-compiler-error


    【解决方案1】:

    使用括号,要更新的类型来自 type-id,在本例中为 X[n]。这是一个可变长度数组,不是标准行为。如果没有括号,则要更新的类型是 new-type-id,即 X 的数组。

    【讨论】:

    • 如果是的话new(buf)(X)和new(buf)X是一样的吗?谢谢
    • @KenmanTsang 是的,如果我对标准语言的理解是正确的。
    • @Nik-Lz type-idnew-type-id 来自语言规范。你可以看看他们是什么on cppreference.com
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 2019-03-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多