Ответ 1
Если мы посмотрим на примечания к выпуску gcc 4.9, похоже, что они добавили поддержку для инициализации VLA, ожидая, что VLA будет поддерживаться в будущей версии C++:
G++ поддерживает C++ 1y массивы переменной длины. G++ долгое время поддерживал GNU/C99-стиль VLA, но теперь дополнительно поддерживает инициализаторы и захват лямбда по ссылке. В режиме 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 с избыточными элементами инициализатора имеет комментарий, который содержит некоторые сведения об этой функции:
(В ответ на Jakub Jelinek из комментария № 16)
Ошибка здесь в G++, принимающая инициализатор VLA с большим количеством элементов, чем есть место для VLA, а затем сбрасывание стека во время выполнения с дополнительными элементами. Это регрессия в отношении GCC 4.9.3, которая реализует VLA C++, как указано в n3639 (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/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++ VLAs будет более безопасным для использования с патчем, указанным в комментарии # 9. Патч должен был быть возвращен из GCC 6.0, поскольку он вызвал проблемы на Java. Java был удален, и я планирую/надеюсь повторно отправить патч для GCC 8. (Я хотел сделать это для GCC 7, но не добрался до него).