Почему массив переменной длины запрещен: «C90 запрещает массив переменной длины»? - PullRequest
1 голос
/ 22 декабря 2011

Я знаю, что я не должен делать это в C90, и это довольно простой материал.

char name[strlen(s)];

ArrayLength.c:11: warning: ISO C90 forbids variable length array ‘name’

Они хотели, чтобы я специально использовал malloc?Я просто интересуюсь логикой, стоящей за этим.

Ответы [ 4 ]

8 голосов
/ 22 декабря 2011

Это запрещено, потому что C90 не поддерживает массивы переменной длины (VLA). Это действительно так просто.

Ваши варианты:

  • Объявите массив фиксированной длины, который может работать с максимальной длиной строки, с которой вы хотите работать.
  • Динамически распределить массив (используя malloc).
  • Работа с компилятором, который предлагает VLA нестандартное расширение языка, например GCC. (Я не рекомендую это, потому что это означает, что вы в конечном итоге будете писать непереносимый код.)
  • Вместо этого используйте C99, где поддерживаются VLA. Обратите внимание, что VLA размещаются в стеке, что может вызвать всевозможные проблемы, если вы исчерпаете пространство стека (в отличие от malloc, нет никакой возможности проверить, было ли выделение выполнено успешно).

[ Примечание: Если вы выделяете массив для создания копии s, вам нужно будет использовать strlen(s)+1 в качестве размера (запомните нулевой терминатор) ). ]

1 голос
/ 22 декабря 2011

Дело не в том, что «они» не хотят, чтобы вы это делали, это просто не часть языка (точнее, не до 1999 года).Стандартный обходной путь должен использовать malloc или alloca.(alloca по сути идентично распределению массива переменной длины, но не является стандартной функцией, поэтому она может быть недоступна на всех интересующих системах. Кроме того, некоторые люди имеют серьезные возражения против ее использования, но они склонны возражать противмассивы переменной длины по тем же причинам.)

0 голосов
/ 22 декабря 2011

Дело в том, что язык имеет ограничения для предполагаемого удобства компилятор и предполагаемая среда выполнения.

0 голосов
/ 22 декабря 2011

Это предупреждение указывает на то, что использование расширения GNU gcc является серьезной проблемой переносимости.

Код недопустим, поскольку значение strlen (s) не известно во время компиляции.GNU gcc предоставляет расширение для автоматических массивов, которые выделяются на основе значений времени выполнения;но их использование делает код несоответствующим стандарту.

Если значение strlen (s) неизвестно до времени выполнения, тогда можно привести код в соответствие, либо выполнив преобразование в выполнениевыделение / освобождение явно в массивах соглашений или с использованием контейнеров STL (например, std :: vector).

...