GCC не поддерживает удаление скобок в выражении new - PullRequest
1 голос
/ 29 сентября 2019

Рассмотрим эту программу:

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, но ничего не нашел.

1 Ответ

1 голос
/ 29 сентября 2019

Да, это определенно ошибка.new выражения определены для использования правил прямой инициализации ( [expr.new] /18.2), а скобка elision применяется ко всем случаям агрегатной инициализации ( [dcl.init.aggr] / 12 ).

Если вы не можете найти ошибку после поиска в bugzilla, сообщите об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...