Если посмотреть на примечания к выпуску gcc 4.9 , похоже, что они добавили поддержку инициализации VLA с ожиданием, что VLA будет поддерживаться в будущей версии C ++:
G ++ поддерживает массивы C ++ 1y переменной длины. G ++ долгое время поддерживал VLA в стиле GNU / C99, , но теперь дополнительно поддерживает инициализаторы и лямбда-захват по ссылке. В режиме C ++ 1y G ++ будет жаловаться на использование VLA, которые не разрешены проектом стандарта, такие как формирование указателя на тип VLA или применение sizeof к переменной VLA. Обратите внимание, что теперь кажется, что VLA не будет частью C ++ 14, но будет частью отдельного документа и, возможно, C ++ 17.
Мы можем видеть , что до 4.9 жалуется, что мы не можем инициализировать VLA
error: variable-sized object 'opt' may not be initialized
int opt[rows][cols] = {0};
^
но в 4.9.1 и после он перестает жаловаться, и у него нет той же ошибки, которую мы видим в более поздних версиях .
Так что это похоже на регрессию.
Обратите внимание, что clang отказывается разрешить инициализацию VLA (, которую они поддерживают как расширение ) , см. Живой пример . Что имеет смысл, поскольку C99 не позволяет инициализировать VLA :
Тип объекта, который должен быть инициализирован, должен быть массивом неизвестного размера или типом объекта , который не является типом массива переменной длины.
gcc Ошибка 69517
gcc отчет об ошибке: SEGV в VLA с избыточным количеством элементов инициализатора содержит комментарий, который предоставляет некоторые сведения об этой функции:
(В ответ на Якуба Елинека из комментария № 16)
Ошибка здесь в том, что G ++ принимает инициализатор VLA с большим количеством элементов, чем есть в VLA, а затем уничтожает стек во время выполнения с дополнительными элементами. Это регрессия в отношении GCC 4.9.3, которая реализует VLA C ++, как указано в n3639 (http://www.open -std.org / jtc1 / sc22 / wg21 / docs / paper / 2013 / n3639.html ) , Это задокументировано в изменениях GCC 4.9 (https://gcc.gnu.org/gcc-4.9/changes.html), которые выделяют функцию, используя следующий пример:
void f(int n) {
int a[n] = { 1, 2, 3 }; // throws std::bad_array_length if n < 3
...
VLA впоследствии были удалены из C ++, а также частично (но не полностью) удалены из G ++, что приводит к сбою программ на C ++, разработанных и протестированных с G ++ 4.9, при переносе на более позднюю версию.
C ++ VLA будет безопаснее использовать с патчем, упомянутым в комментарии № 9. Это исправление пришлось вернуть из GCC 6.0, потому что это вызывало проблемы в Java. Java была удалена, и я планирую / надеюсь повторно представить патч для GCC 8. (Я хотел сделать это для GCC 7, но не получил его).