Поиграв с новым размещением для массивов, я придумал (случайно / по ошибке) следующий код:
#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 = новый (buf) (X [n]);
предупреждение: непостоянный массив новой длины должен быть указан без скобок вокруг идентификатора типа [-Wvla] X * p = новый (buf) (X [n]);
затем вылетает с внутренней ошибкой компилятора (ICE) в tree_to_uhwi, в tree.h: 4044. Внутренняя ошибка компилятора появляется только в gcc> = 6.
Мой вопрос: как именно строка, помеченная как «неверная», анализируется / интерпретируется, почему «неправильно» иметь эти скобки? *
* Для ICE, я все равно исправлю ошибку.
РЕДАКТИРОВАТЬ 1 Я только что понял, что ICE / Warning (s) не имеют ничего общего с пользовательскими типами, поэтому такое же поведение наблюдается для int
вместо struct X
,
РЕДАКТИРОВАТЬ 2 ошибка gcc6 заполнена Вот. ICE не появляется в gcc5 или более ранних версиях (отображаются только предупреждения, которые являются правильными).
С круглыми скобками, тип, который будет обновлен, прибывает из тип-идентификатор, в этом случае X[n]
, Это массив переменной длины, который не является стандартным поведением. Без скобок тип для обновления новый тип-идентификатор, массив X
,
Других решений пока нет …