Компилятору часто приходится добавлять код перед main (), чтобы соответствовал стандарту . Поскольку в стандарте указано, что инициализация глобалов / статик должна выполняться до , программа выполняется. И, как уже упоминалось, то же самое касается конструкторов объектов, размещенных в области видимости файла (глобальные переменные).
Таким образом, исходный вопрос относится и к , также относящемуся к C, потому что в программе на C вы все равно должны иметь глобальную / статическую инициализацию до запуска программы.
Стандарты предполагают, что эти переменные инициализируются посредством "магии", потому что они не говорят , как они должны быть установлены до инициализации программы. Я думаю, что они считали это чем-то, выходящим за рамки стандарта языка программирования.
Редактировать: см., Например, ISO 9899: 1999 5.1.2:
Все объекты со статическим хранилищем
продолжительность должна быть инициализирована (установлена на
их начальные значения) перед программой
запускать. Способ и сроки такого
инициализация в противном случае
не определено.
Теория того, как это «волшебство» должно было быть сделано, восходит к рождению Си, когда он был языком программирования, предназначенным для использования только для ОС UNIX на компьютерах с ОЗУ. Теоретически, программа сможет загружать все предварительно инициализированные данные из исполняемого файла в ОЗУ одновременно с загрузкой самой программы в ОЗУ.
С тех пор компьютеры и ОС эволюционировали, и C используется в гораздо более широкой области, чем первоначально предполагалось. Современная ОС ПК имеет виртуальные адреса и т. Д., И все встроенные системы выполняют код из ПЗУ, а не из ОЗУ. Таким образом, существует много ситуаций, когда ОЗУ не может быть установлено «автоматически».
Кроме того, стандарт слишком абстрактен, чтобы что-либо знать о стеках, памяти процесса и т. Д. Эти вещи также должны быть выполнены до запуска программы.
Следовательно, почти каждая программа на C / C ++ имеет некоторый код init / "copy-down", который выполняется перед вызовом main для соответствия правилам инициализации стандартов.
В качестве примера, встроенные системы обычно имеют опцию, называемую «запуск, не совместимый с ISO», при котором весь этап инициализации пропускается по соображениям производительности, а затем код фактически запускается непосредственно из main. Но такие системы не соответствуют стандартам, так как нельзя полагаться на значения инициализации глобальных / статических переменных.