Рассмотрим эту программу:
struct S {
int m;
};
int main() {
S s_arr[1]{0};
S *s_new = new S[1]{0};
int i_arr[1][1]{0};
int (*i_new)[1] = new int[1][1]{0};
return 0;
}
Я думаю, что все четыре переменные в основной функции должны быть инициализированы с использованием агрегатной инициализации.
Однако GCC принимает только s_arr
и i_arr
, но отклоняет s_new
и i_new
, отчеты (g ++ 8.3.0 в Ubuntu):
test.cpp: In function ‘int main()’:
test.cpp:7:26: error: could not convert ‘0’ from ‘int’ to ‘S’
S *s_new = new S[1]{0};
^
test.cpp:9:38: error: array must be initialized with a brace-enclosed initializer
int (*i_new)[1] = new int[1][1]{0};
^
test.cpp:9:38: error: array must be initialized with a brace-enclosed initializer
(примечание: последняя дублирующая строка создается g ++)
Я такжепротестировано на godbolt , ни одна из версий gcc от 6.1 до 9.2 не может скомпилировать эту программу.В версиях 6.x и 7.x также появляется сообщение: « извините, не реализовано: невозможно инициализировать многомерный массив с инициализатором » для i_new
.
Изменение {0}
на{{0}}
разрешает как s_new
, так и inew
для всех версий GCC, протестированных на Godbolt (от 6.1 до 9.2).Я могу понять это, так как оба S[1]
и int[1][1]
являются агрегатными типами, чей тип элемента является субагрегатом (массив S
; массив массива).Однако C ++ позволяет исключить эти фигурные скобки, а GCC принимает s_arr
и i_arr
, где эти фигурные скобки исключены.
С другой стороны, clang с 6.0.0 по clang 9.0.0 принимает оригиналпрограмма счастливо.
В спецификации C ++ 14 (gnu ++ 14 по умолчанию для GCC 6.5 / 7.4 / 8.3 / 9.2),
5.3.4 New /17
Новое выражение, создающее объект типа T, инициализирует этот объект следующим образом:
......
(17.2) - В противном случае новое-initializer интерпретируется в соответствии с правилами инициализации 8.5 для прямой инициализации.
Новый инициализатор должен интерпретироваться как прямая инициализация.Поскольку s_arr
и i_arr
также имеют прямую инициализацию, я думаю, что они должны интерпретироваться таким же образом, и исходная программа должна быть правильно сформирована.
Есть ли что-то, что я здесь упускаю,или это ошибка в GCC?
Я пытался искать в GCC Bugzilla, но ничего не нашел.