Почему переменные начинаются со случайных значений в C - PullRequest
3 голосов
/ 14 декабря 2010

Я думаю, что это неправильно, оно должно начинаться с NULL, а не со случайного значения.Если у вас есть указатель со случайным адресом памяти в качестве значения по умолчанию, это может быть очень опасно, не так ли?

Ответы [ 7 ]

5 голосов
/ 14 декабря 2010

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

Если вы хотите, чтобы переменная была инициализирована после создания,просто инициализируй это.:)

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

3 голосов
/ 14 декабря 2010

Нет.C - очень эффективный язык, традиционно более быстрый, чем многие другие языки.Одна из причин этого заключается в том, что он не делает слишком много сам по себе.Программист контролирует это.

В случае инициализации переменные C не инициализируются случайным значением.Скорее, они не инициализируются и поэтому содержат то, что было в ячейке памяти ранее.

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

2 голосов
/ 14 декабря 2010

Скорость исполнения и накладные расходы (или их отсутствие) являются основными причинами этого.C печально известен тем, что позволил вам уйти от пресловутого утеса, потому что он всегда предполагает, что пользователь знает лучше, чем он.

Обратите внимание, что если вы объявили переменную как static, это на самом деле равно гарантированно будет инициализирован до 0.

1 голос
/ 14 декабря 2010

Это не имеет ничего общего с "если C разрабатывался сегодня" или с эффективностью одной инициализации. Вместо этого придумайте что-то вроде

void foo()
{
    struct bar *ptrs[10000];
    /* do something where only a few indices end up actually getting used */
}

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

Если вам не нравится мой пример с таким большим объектом в стеке, замените malloc вместо него. Он имеет ту же семантику в отношении инициализации.

В любом случае, если вы хотите инициализировать нулем, вы можете получить его с помощью {0} или calloc.

1 голос
/ 14 декабря 2010

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

1 голос
/ 14 декабря 2010

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

0 голосов
/ 14 декабря 2010

Это был дизайнерский выбор, сделанный много лет назад, вероятно, из соображений эффективности.

Статически распределенные переменные (глобальные и статические) инициализируются равными 0, если нет явной инициализации - это может быть оправдано, даже принимая во внимание эффективность, потому что это происходит только один раз. Я предполагаю, что мысль была о том, что для автоматических переменных (локальных), которые выделяются каждый раз при вводе области, неявная инициализация считалась чем-то, что могло бы стоить слишком дорого и поэтому должно быть оставлено на усмотрение программиста.

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

Тем не менее, существует так много инструментальных цепочек компилятора C, которые следуют спецификации не инициализации автоматически, для компилятора было бы глупо выполнять неявную инициализацию для «полезного» значения (например, 0 или NULL). Это просто побудило бы людей, нацеленных на эту цепочку инструментов, писать код, который некорректно работал с другими цепочками инструментов.

Однако компиляторы могут инициализировать локальные переменные, и они часто это делают. Просто они инициализируют локальные значения значениями, которые обычно бесполезны (особенно если они не устанавливают указатель на нулевой указатель). Этот тип инициализации бесполезен при написании вашей логики программирования и не предназначен для этого. Он предназначен для того, чтобы вызывать детерминированные и воспроизводимые ошибки, так что если вы ошибочно используете значения, которые были установлены неявной инициализацией, вы сможете легко найти их в test / debug.

Обычно это поведение компилятора включено только для отладочных сборок; Я мог видеть аргумент для включения его в сборках релиза - особенно, если сборка релиза все еще может оптимизировать его, когда компилятор может доказать, что неявное инициализированное значение никогда не используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...