Скобки вокруг размещения нового оператора для массивов
Поиграв с новым размещением для массивов, я придумал (случайно / по ошибке) следующий код:
#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
,