Почему C ++ допускает массивы переменной длины, которые не выделяются динамически? - PullRequest
7 голосов
/ 09 апреля 2010

Я относительно новичок в C ++, и с самого начала мне дошло, что вы не можете делать что-то вроде

int x;
cin >> x;
int array[x];

Вместо этого вы должны использовать динамическую память. Однако недавно я обнаружил, что вышеприведенный будет скомпилирован (хотя я получаю предупреждение с предупреждением о том, что это запрещено ISO C ++). Я знаю, что, очевидно, это плохая идея, если это не разрешено стандартом, но раньше я даже не знал, что это возможно.

Мой вопрос: почему g ++ допускает массивы переменной длины, которые не выделяются динамически, если это не разрешено стандартом? Кроме того, если это возможно для компилятора, почему не это в стандарте?

Ответы [ 4 ]

19 голосов
/ 09 апреля 2010

Поддержка языков переменной длины (VLA) была добавлена ​​к языку C в C99.

Вероятно, поскольку их поддержка существует в gcc (для поддержки C99), добавить поддержку их в g ++ было относительно просто.

Тем не менее, это расширение для конкретной реализации, и не стоит использовать расширения для конкретной реализации, если вы хотите, чтобы ваш код был переносимым.

5 голосов
/ 09 апреля 2010

Потому что это поддерживается в C99. Я не могу говорить, почему это не в стандарте C ++. Тем не менее, это не так полезно, как вы думаете, потому что это легко приводит (если вы не будете осторожны) к переполнению стека (поскольку обычно оно основано на alloca , что само по себе нестандартно). Другая ошибка заключается в возвращении указателя на динамический массив, который немедленно выйдет из области видимости.

3 голосов
/ 09 апреля 2010

Партия компиляторов охватывает и расширяет стандарты. Есть две основные причины:

  1. Небезызвестные авторы компиляторов, вероятно, думают, что усложнение перехода от их компилятора помогает увеличить продолжительность жизни.
  2. Доброжелательные авторы компиляторов, вероятно, считают, что дать вам больше возможностей, когда они могут практически без затрат для себя, - это хорошо.
1 голос
/ 10 апреля 2010

Все причины, упомянутые в связи с их нахождением в C, верны, хотя для этого требования есть ограничения. Ваш пример может продемонстрировать более гибкую поддержку, чем требуется в C (если вы реализовали это с использованием scanf, а не cin, поместите его в файл .c и использовали gcc).

Это почти просто неявный вызов alloca (allocate auto), который просто уменьшает указатель стека (увеличивает размер стека) и копирует новый указатель стека в другой регистр, который используется как указатель на выделенную память.

Разница в том, что конструкторы и деструкторы не будут вызываться для объектов, созданных с помощью alloca.

...