Скобки вокруг размещения нового оператора для массивов

Поиграв с новым размещением для массивов, я придумал (случайно / по ошибке) следующий код:

#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++ выплевывает

предупреждение: когда тип указан в скобках, массив не может иметь динамический размер

пока gcc6 выводит

предупреждение: ISO C++ запрещает массив переменной длины [-Wvla] X* p = new (buf) (X[n]);

предупреждение: непостоянный массив новой длины должен быть указан без скобок вокруг идентификатора типа [-Wvla] X* p = new (buf) (X[n]);

затем происходит сбой с внутренней ошибкой компилятора (ICE) в tree_to_uhwi, в tree.h: 4044. Внутренняя ошибка компилятора появляется только в gcc >= 6.

Мой вопрос: как именно строка, помеченная как "неверная", анализируется / интерпретируется, почему "неправильно" иметь эти скобки? *

* Для ICE, я все равно исправлю ошибку.

РЕДАКТИРОВАТЬ 1 Я только что понял, что ICE/ предупреждение (я) не имеют ничего общего с пользовательскими типами, поэтому такое же поведение наблюдается для int вместо struct X,

РЕДАКТИРОВАТЬ 2 gcc6 ошибка заполнена здесь. ICE не появляется в gcc5 или более ранних версиях (отображаются только предупреждения, которые являются правильными).

1 ответ

Решение

С круглыми скобками, тип, который будет обновлен, прибывает из идентификатора типа, в этом случае X[n], Это массив переменной длины, который не является стандартным поведением. Без круглых скобок тип, который будет обновлен, - это новый тип-идентификатор, массив X,

Другие вопросы по тегам