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

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

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

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

Источник: Wikipedia