Массив размера, определяемого непостоянной переменной

#c #arrays

#c #массивы

Вопрос:

Есть такой код:

 #include <iostream>

int main()
{
  int size;
  std::cin >> size;

  size = size   1;
  int tab3[size];

  tab3[0] = 5;
  std::cout << tab3[0] << " " << sizeof(tab3) << std::endl;
  return 0;
}
  

Результатом является:

 $ g   prog.cpp -o prog -Wall -W 
$ ./prog
5
5 24
  

Почему этот код вообще компилируется? Разве длина массива не должна быть постоянной переменной?

Я использовал g версии 4.4.5.

Ответ №1:

Массивы переменной длины в C доступны как расширение в GCC. Компиляция со всеми предупреждениями должна была предупредить вас об этом факте (включить -pedantic ).

Комментарии:

1. 1, хотя я понятия не имел sizeof() , также может быть непостоянным. Если бы я когда-нибудь подумал об использовании sizeof() для этого, я бы ожидал, что по какой-то причине это завершится неудачей.

2. @MichaelKrelin-хакер: опять же, в качестве расширения… Для VLAS требуется среда выполнения sizeof() , поэтому это часть стандарта C99. Это просто не очень похоже на C . Подумайте о decltype и обо всем этом…

3. Интересно, однако, что, по-видимому, не существует какого -либо стандартизированного метода выделения памяти в стеке. Мы могли бы обработать построение объекта с помощью placement-new, но в C просто невозможно получить переменный объем необработанной памяти в стеке.

4. Конечно, я не сомневаюсь, что это стандарт, просто я понятия не имел и никогда не думал об этом. Вероятно, alloca() не стандартизирован, но он довольно распространен, не так ли?

5. Было предложение рассмотреть также VLA в C , но комитет по стандартам отклонил его, поскольку они сочли, что изменения в системе типов для ее поддержки намного перевешивают гибкость, которую они могли бы обеспечить.

Ответ №2:

Это функция C99, а не часть C . Обычно на них ссылаются как на VLA (массивы переменной длины.

Если вы запустите g с -pedantic , он будет отклонен.

Смотрите Документы GCC для получения дополнительной информации.

Смотрите также: VLAS — это зло.

Ответ №3:

GCC предоставляет массивы VLA или переменной длины. Лучшей практикой является создание указателя и использование new ключевого слова для выделения пространства. VLA-файлы недоступны в MSVC, поэтому второй вариант лучше подходит для кроссплатформенного кода