Всегда ли неинициализированные глобальные переменные всегда по умолчанию равны 0 в c? - PullRequest
2 голосов
/ 14 апреля 2011

Я знаю, что неинициализированные глобалы восстанавливаются в сегменте BSS, и ОС должна инициализировать его нулями.

Но это должно , а не должно , и я никогда не видел ни одного стандартного высказывания о том, что неинициализированные глобалы должны быть по умолчанию нулями, поэтому безопасно ли принять это как должное?

Ответы [ 3 ]

5 голосов
/ 14 апреля 2011

Вот аутентичный ответ из C99 Standard Document , пункт 6.7.8 (параграф 10):

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

  • , если он имеет тип указателя, он инициализируется нулевым указателем;
  • , если он имеет арифметический тип,он инициализируется нулевым (положительным или беззнаковым);
  • , если он является агрегатом, каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами;
  • , если это объединение, первое имяэлемент инициализируется (рекурсивно) в соответствии с этими правилами.
3 голосов
/ 14 апреля 2011

Стандарт C говорит, что переменные со статической продолжительностью хранения (которая включает в себя все глобальные переменные) без явной инициализации инициализируются нулем.

Другие языки, такие как фортран, отличаются.

0 голосов
/ 14 апреля 2011

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

Лично я стараюсь никогда принимать что-либо как должное.Мало того, что это делает явным, аккуратно обходят любые такие проблемы, но он также дает понять, кто читает ваш код, что вы ожидаете, чтобы иметь дело.

РЕДАКТИРОВАТЬ: Я имеюс тех пор было исправлено, что стандарты do требуют инициализации глобалов на ноль.Просто чтобы прояснить мою плохую формулировку выше, я не имею в виду, что абсолютно ничто не может считаться само собой разумеющимся (это абсурд), а скорее, что если есть простой и краткий способ не , принимающий что-то как должное, сделайте это.

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

Когда я вижу int myGlobal=0; вфайл, я знаю наверняка , что myGlobal имеет значение ноль.Если он просто объявлен как int myGlobal;, то в стандарте сказано, что также должно иметь значение ноль.Это не гарантирует, что будет , и я считаю, что ввод дополнительных двух символов не требует больших затрат, повышает удобочитаемость программы и повышает переносимость, если вы обнаружите, что вам когда-нибудь понадобится скомпилировать код наплатформа, которая не инициализирует глобальные переменные. Это моя точка зрения - почему бы и нет, и вы можете просто прикрыть себя, даже если в стандарте говорится, что должно быть в порядке.

...