Это был дизайнерский выбор, сделанный много лет назад, вероятно, из соображений эффективности.
Статически распределенные переменные (глобальные и статические) инициализируются равными 0, если нет явной инициализации - это может быть оправдано, даже принимая во внимание эффективность, потому что это происходит только один раз. Я предполагаю, что мысль была о том, что для автоматических переменных (локальных), которые выделяются каждый раз при вводе области, неявная инициализация считалась чем-то, что могло бы стоить слишком дорого и поэтому должно быть оставлено на усмотрение программиста.
Если бы C разрабатывался сегодня, я бы не удивился, если бы это дизайнерское решение было изменено - тем более что компиляторы достаточно умны сегодня, чтобы иметь возможность оптимизировать инициализацию, которая перезаписывается перед любым другим использованием (или возможным использованием) .
Тем не менее, существует так много инструментальных цепочек компилятора C, которые следуют спецификации не инициализации автоматически, для компилятора было бы глупо выполнять неявную инициализацию для «полезного» значения (например, 0 или NULL). Это просто побудило бы людей, нацеленных на эту цепочку инструментов, писать код, который некорректно работал с другими цепочками инструментов.
Однако компиляторы могут инициализировать локальные переменные, и они часто это делают. Просто они инициализируют локальные значения значениями, которые обычно бесполезны (особенно если они не устанавливают указатель на нулевой указатель). Этот тип инициализации бесполезен при написании вашей логики программирования и не предназначен для этого. Он предназначен для того, чтобы вызывать детерминированные и воспроизводимые ошибки, так что если вы ошибочно используете значения, которые были установлены неявной инициализацией, вы сможете легко найти их в test / debug.
Обычно это поведение компилятора включено только для отладочных сборок; Я мог видеть аргумент для включения его в сборках релиза - особенно, если сборка релиза все еще может оптимизировать его, когда компилятор может доказать, что неявное инициализированное значение никогда не используется.