Объявление размера массива для динамически выделенного массива со списком инициализаторов

#c #gcc #visual-c #language-lawyer #dynamic-arrays

Вопрос:

Я пытаюсь инициализировать динамически объявленный массив с помощью списка инициализаторов, но я заметил, что мне нужно указать размер массива с помощью GCC, иначе я получу ошибку. Попытка сделать то же самое с помощью MSVC не приведет к каким-либо ошибкам, если не указан размер массива. Является ли предоставление размера массива при использовании списка инициализаторов с динамическими массивами обязательным или нет? Является ли это чем-то определяемым реализацией, поэтому оно отличается для обоих компиляторов?

 int *array { new int [3] {0, 1, 2} }; // Works with both MSVC and GCC.
int *array { new int [] {0, 1, 2} }; // Works only with MSVC, not GCC.
 

Комментарии:

1. Clang также поддерживает обе демо -версии.

2. ( initializer-list тег относится к std::initializer_list )

3. Не на 100%, и я не могу изложить все детали, но я думаю, что g здесь не прав, и вторая версия должна быть принята. Эта ссылка также приводится double* p = new double[]{1,2,3}; в качестве рабочего примера.

4. github.com/cplusplus/draft/commit/…

Ответ №1:

Это P1009R2: Вычет размера массива в новых выражениях, который был реализован для C 20.

Бьярне Страуструп указал на следующее несоответствие в языке C :

 double a[]{1,2,3}; // this declaration is OK, ...
double* p = new double[]{1,2,3}; // ...but this one is ill-formed!
 

Йенс Маурер объяснил, почему это не работает: для нового выражения выражение
в квадратных скобках в настоящее время является обязательным в соответствии с грамматикой C . Когда
для C 11 была введена единообразная инициализация, правило о выводе размера массива из
числа инициализаторов никогда не распространялось на случай нового выражения. По-видимому, это было просто
упущено из виду. Нет никакой фундаментальной причины, по которой мы не можем заставить это работать […]

Предлагаемая формулировка

Сообщенная проблема предназначена для отчета о дефектах с предлагаемым решением следующим образом. Эффект изменений формулировок должен применяться в реализациях всех предыдущих версий C , где они применяются. […]

На страницах поддержки стандартов C GCC мы можем отметить, что GCC перечисляет P1009R2, реализованный начиная с GCC 11, и мы можем проверить, что GCC 11 перенес реализованный, чтобы принять пример OP, который был сформирован еще в C 11.

ДЕМОНСТРАЦИОННАЯ ВЕРСИЯ (GCC 11 / -std=c 11 ).

Комментарии:

1. Спасибо за ваш ответ. Я предполагаю, что мой вопрос тогда в том, почему это не работает для меня, если это уже было реализовано GCC. imgur.com/a/LtgDwTh

2. @MohammadAli Смотрите последнюю часть моего ответа: это было реализовано для GCC 11; любая версия до этого (скажем, GCC 10) не содержит этой функции. Поскольку GCC 11 является передовым, вы, скорее всего, используете более старую версию в своей собственной цепочке инструментов.

3. Спасибо, я ошибочно принял это за то, что мне нужно использовать стандарт C 11 или более позднюю версию.