Как и следовало ожидать, для этого поведения также существуют причины, основанные на эффективности.
Пространство в стеке обычно выделяется просто путем корректировки указателя стека. Если у вас есть 32 байта простых переменных в функции, тогда компилятор испускает команду, эквивалентную «sp = sp - 32» Любая инициализация этих переменных потребует дополнительного кода и времени выполнения - следовательно, они в конечном итоге инициализируются, по-видимому, случайными значения.
Глобальные переменные - это еще один зверь целиком. Простые переменные эффективно распределяются программным загрузчиком и могут быть расположены в так называемом «BSS». Эти переменные почти не занимают места в исполняемом файле. Все они могут быть объединены вместе в один блок - поэтому исполняемому изображению требуется только указать размер блока. Поскольку ОС должна гарантировать, что новый процесс не сможет увидеть какие-либо оставшиеся данные в памяти из некоторого теперь мертвого процесса, память должна быть заполнена чем-то - и вы можете также заполнить ее нулями.
Глобальные переменные, которые инициализируются не-нулями, фактически занимают место в исполняемом файле, они отображаются как блок данных и просто загружаются в память - в инициализации нет кода для инициализации.
C++ также позволяет глобальным переменным, которые требуют выполнения кода для инициализации, C не позволяет этого. Например, "int x = rand();" Инициализируется во время выполнения кодом в исполняемом файле.
Попробуйте добавить эту глобальную переменную int x [1024 * 1024]; и посмотреть, не имеет ли значение размер исполняемого файла. Теперь попробуйте: int x [1024 * 1024] = {1,2,3}; И посмотрите, какая разница.
Я по-прежнему считаю, что это хорошая идея быть явной в обеих ситуациях, и это указывает читателю вашего кода, что вы думали об исходном значении. –
Представьте, сколько меньше ошибок в коде C/C++ в мире, если по умолчанию было инициализировать все переменные до нуля. Так как локальный «int x;», x гарантированно равен нулю. Если вам действительно нужна производительность, вы можете написать что-то вроде «uninitialized int x;» – joeking
@ joeking: Когда есть несколько вариантов, C и C++ выбрали (и по-прежнему выбирают) тот, который более эффективен. Local: 'int x [10000];' все элементы x равно * uninitialized * по умолчанию (по причине производительности); если вам действительно нужно, чтобы они были нулевыми инициализированными, напишите: 'int i [10000] = {0};' теперь все элементы гарантированно равны нулю. :-) – Nawaz