#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};
в качестве рабочего примера.
Ответ №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 или более позднюю версию.