Какое преимущество имеет там разрешение переменной быть оставленным неинициализированным?

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

Например, в C++, можно записать отрывок, такой как:

int x;
cout << x;

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

Есть ли некоторое приложение для или эффективность, которая следует из разрешения использования неинициализированной памяти?

править: Мне пришло в голову, что отъезд инициализации до пользователя минимизирует записи для носителя памяти, который ограничил продолжительность жизни (циклы записи). Просто определенный пример в соответствии с вышеупомянутым заголовком 'производительности'. Спасибо.

8
задан ozmo 9 August 2010 в 02:27
поделиться

8 ответов

Мои мысли (а я и раньше ошибался, спросите мою жену) заключаются в том, что это просто пережиток более ранних воплощений языка.

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

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

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

В C++ (и более поздних воплощениях C), где вы можете создать свою переменную в любом месте функции, вы действительно должны создать ее и инициализировать одновременно. Но в ранних версиях это было невозможно. Приходилось использовать что-то вроде:

int fn(void) {
    int x, y;
    /* Do some stuff to set y */
    x = y + 2;
    /* Do some more stuff */
}

Сейчас я бы выбрал:

int fn(void) {
    int y;
    /* Do some stuff to set y */
    int x = y + 2;
    /* Do some more stuff */
}
13
ответ дан 5 December 2019 в 06:36
поделиться

Некоторые API предназначены для возврата данных через переданные переменные, например:

bool ok;
int x = convert_to_int(some_string, &ok);

Она может установить значение 'ok' внутри функции, так что инициализировать ее - пустая трата времени.

(Я не защищаю этот стиль API.)

.
4
ответ дан 5 December 2019 в 06:36
поделиться

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

например.

int x;
if (external_function() == 2) {
   x = 42;
} else if (another_function() == 3) {
   x = 49;
}
yet_another_function( &x );
cout << x;   // Is this a use-before-definition?

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

Другой вопрос, должен ли язык допускать концепцию неинициализированных переменных. В C # несколько необычно определение каждой переменной как инициализируемой значением по умолчанию. Большинство языков (C ++ / C / BCPL / FORTRAN / Assembler / ...) оставляют на усмотрение программиста, подходит ли инициализация. Хорошие компиляторы иногда могут обнаружить ненужные инициализации и устранить их, но это не само собой разумеющееся. Компиляторы для более непонятного оборудования, как правило, прилагают меньше усилий к оптимизации (что является сложной частью написания компилятора), поэтому языки, нацеленные на такое оборудование, как правило, не требуют генерации ненужного кода.

2
ответ дан 5 December 2019 в 06:36
поделиться

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

1
ответ дан 5 December 2019 в 06:36
поделиться

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

0
ответ дан 5 December 2019 в 06:36
поделиться

стиль цикла for

int i;
for(i=0;i<something;++i){
    .......
}
do something with i

и вы бы предпочли, чтобы цикл for выглядел как for(init;condition;inc)

вот один из них, в котором есть абсолютная необходимость

bool b;
do{
    ....
    b = g();
    ....
}while(!b);

горизонтальная площадь экрана с длинными вложенными именами

более долгоживущий scoping для отладочной наглядности

очень иногда производительность

0
ответ дан 5 December 2019 в 06:36
поделиться

В некоторых языках есть значения по умолчанию для некоторых типов переменных. При этом я сомневаюсь, что на любом языке есть преимущества в производительности, если их явно не инициализировать.Однако есть и обратные стороны:

  • Возможность того, что его нужно инициализировать, а без этого вы рискуете потерпеть крах
  • Непредвиденные значения
  • Отсутствие ясности и цели для других программистов

Мое предложение всегда инициализировать ваши переменные и последовательность окупится.

1
ответ дан 5 December 2019 в 06:36
поделиться

Старейшая отговорка в программировании: это улучшает производительность!

edit: прочтите ваши комментарии, и я согласен - много лет назад производительность была сосредоточена на количестве циклов процессора. Моим первым компилятором C был традиционный C (тот, который был до ANSI C), и он позволял компилировать всевозможные мерзости. В наше время производительность - это количество жалоб клиентов. Когда я говорю новым выпускникам, которых мы нанимаем: «Меня не волнует, насколько быстро программа даст неправильный ответ». Используйте все инструменты современных компиляторов и разработчиков, пишите меньше ошибок и каждый сможет вернуться домой вовремя.

4
ответ дан 5 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: