2010-01-19 3 views
52

В C/C++, почему глобальные переменные и статические переменные инициализируются значениями по умолчанию?Почему глобальные и статические переменные инициализируются значениями по умолчанию?

Почему бы не оставить его только с мусорными знаками? Существуют ли какие-либо специальные причины для этого? ?

ответ

62
  1. безопасности: оставив память в одиночку бы утечку информации из других процессов или ядра.

  2. Эффективность: значения бесполезны, пока не инициализируются к чему-то, и это более эффективно обнулить их в блоке с развернутыми циклами. ОС может даже обнулять лишние страницы, когда система в противном случае не работает, а не когда клиент или пользователь ждут запуска программы.

  3. Воспроизводимость: оставляя значения в одиночку бы поведение программы неповторяющиеся, что делает ошибки очень трудно найти.

  4. Elegance: она чище, если программы могут начинаться с 0, не загромождать код по умолчанию инициализаторах.

Можно было бы потом удивляется, почему класс auto хранения делает начала как мусор. Ответ два раза:

  1. Это не делает, в некотором смысле. Первая страница кадра кадра на каждом уровне (то есть каждая новая страница, добавленная в стек) получает нулевые значения. Значения «мусор» или «неинициализированные», которые представляют собой последующие экземпляры функций на одном уровне стека, действительно являются предыдущими значениями, оставленными другими экземплярами метода вашей собственной программы и ее библиотеки.

  2. Там может быть квадратичным (или любой другой) выполнения снижает производительность, связанные с инициализацией auto (функция местных жителей) ни к чему. Функция может не использовать какой-либо или весь большой массив, скажем, для любого данного вызова, и его можно было бы вызывать тысячи или миллионы раз. Инициализация статики и глобалов, OTOH, должна произойти только один раз.

+2

Я предполагаю, что спрашивающий хочет знать, почему 'статический Int х;' 'всегда делают x' инициализируется нулем, а' ИНТ х; '' x' оставляет сборщиком. – kennytm

+0

Хм, возможно, вы правы, я пересмотрел ответ, чтобы ответить на этот вопрос. – DigitalRoss

+3

На самом деле, настоящая причина в том, что первоначальный стандарт C заключался в том, чтобы кодифицировать существующую практику, а не вводить новые вещи. И pre-ANSI/ISO C сделал это для повышения эффективности. – paxdiablo

22

Поскольку при правильном взаимодействии ОС 0 инициализация статики и глобальных переменных может быть реализована без накладных расходов во время выполнения.

+0

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

6

Подумайте об этом, в статическом царстве вы не можете всегда сказать, что что-то действительно инициализировано, или что основное начало. Существует также статический init и динамическая фаза init, статическая первая сразу после динамической, где имеет значение порядок.

Если у вас не было обнуления из статики, вы были бы совершенно неспособны рассказать на этом этапе наверняка, если что-то было инициализировано ВСЕ, а вкратце мир C++ разлетел бы и основные вещи, такие как одиночные (или любые тип динамического статического init), будет просто перестать работать.

Ответ с пулевыми точками является восторженным, но немного глупым. Все они могут применяться к нестатистическому распределению, но это не сделано (ну, иногда, но не обычно).

+0

Точка о синглонах сначала звучит убедительно, но я не уверен, что она действительно имеет значение : Как компиляторы хранят свои уже созданные флагов y/n, это деталь реализации, и они наверняка будут свободны только до нуля _those_ до запуска. Остальное слишком легкомысленно, не объясняя самого себя. Также: «статический первый сразу после динамического»? статичный «первый»? или это «сразу после динамического»? и в чем разница? Кроме того, порядок декларирования имеет значение во всех случаях, когда объекты зависят друг от друга, независимо от продолжительности хранения, не так ли? –

15

Раздел 6.7.8 Инициализация стандарта C99 (n1256) отвечает на этот вопрос:

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

- если у него есть тип указателя, он инициализируется нулевым указателем;

- если у него арифметический тип, он инициализируется (положительным или без знака) нулем;

- если это совокупность, каждый член инициализируется (рекурсивно) в соответствии с этими правилами;

- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами.

+4

Не отвечает на вопрос ОП. Он знает все это. Он спросил * почему. * -1 – EJP

+3

Да, если «C/C++» в вопросе означает стандарт C/C++, мой ответ не имеет значения. В противном случае это актуально. –

2

В C объекты с статическим распределением без явного инициализатора инициализируются нулем (для арифметических типов) или нулевым указателем (для типов указателей). Реализации C обычно представляют собой нулевые значения и значения нулевого указателя, используя битовый шаблон, состоящий исключительно из нулевых битов (хотя это не требуется стандартом C). Следовательно, раздел bss обычно включает в себя все неинициализированные переменные, объявленные в области файла (то есть вне любой функции), а также неинициализированные локальные переменные, объявленные с ключевым словом static.

Источник: Wikipedia

+0

Вопрос в том, почему это происходит. Просто вставить цитату, повторяющую, что происходит, не является ответом на это. –

Смежные вопросы