Массивы переменной длины начинаются со значения по умолчанию 0 в C? - PullRequest
2 голосов
/ 19 февраля 2020

Я знаю, что не может инициализировать массивы переменной длины в C с явно предоставленными значениями. Следующий код не поддерживается:

void main() {
  int l = 2;
  float test[l] = {1.0, 2.0};  // my compiler says: "Variable-sized object may not be initialized"
}

Мой вопрос: если я не попытаюсь дать какие-либо значения:

void main() {
  int l = 2;
  float test[l];
}

… будет C компилятор должен по умолчанию инициализироваться нулем?

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Массивы переменной длины не инициализируются по умолчанию и не могут быть инициализированы явно, за исключением того, что процедуры выделения памяти, такие как calloc, могут инициализировать пространство.

C 2018 6.7.6.2 («Деклараторы массива» ) 2 говорит:

… Если идентификатор объявляется как объект со стати c или продолжительностью хранения потока, он не должен иметь тип массива переменной длины.

Таким образом, продолжительность хранения массива переменной длины должна быть одной из других длительностей хранения: automati c или выделенная [6.2.4 1]. (Существует временная продолжительность хранения, но только для структур или объединений [6.2.4 7].)

6.7.9 10 говорит, что объекты с автоматическим c сроком хранения не инициализируются по умолчанию:

Если объект, имеющий автоматическую c продолжительность хранения, не инициализируется явно, его значение является неопределенным…

Кроме того, 6.7.9 3 говорит, что вы не можете инициализировать массивы переменной длины явно :

Тип инициализируемого объекта должен быть массивом неизвестного размера или полным типом объекта, который не является типом массива переменной длины.

0 голосов
/ 19 февраля 2020

Рад принять лучше задокументированные ответы, но эмпирически ответ: нет : память не инициализируется нулями.

Часто используются следующие варианты кода (но не всегда!) abort:

int main() {
  int l = 99;
  float test[l];
  assert(test[0] == 0.0);
  assert(test[42] == 0.0);
  return 0;
}

Так что, если я не уверен, что инициализирую каждого члена, я должен перевести его в известное состояние, например

int main() {
  int l = 99;
  float test[l];
  memset(test, 0, sizeof test);

 // …now the array content is in a known state…
}

Я считаю, что C ++ ведет себя по-разному , что, вероятно, я и запомнил.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...