• Почему перемещение объявления и инициализации переменной на новую строчку кода влияет на результат работы программы?

    Adamos
    @Adamos
    Я правильно понял, если после объявления неопределенной переменной X начать объявлять или менять значения другим переменным, то X "засорится"?

    Наоборот.
    int i;
    Под переменную i выделен участок стека, лежащее в нем значение не меняется. Но в учебной программе из пары строк там, скорее всего, будет 0, и это создаст иллюзию, что все нормально. Кроме того, некоторые компиляторы в некоторых условиях инициализируют любые переменные, что еще больше запутывает ситуацию.
    int i;
    for(int n = 0; n < 10; ++n) {}

    Под переменную i выделен участок стека, лежащее в нем значение не меняется.
    Под переменную n выделен следующий участок стека, его изменение никак на i не сказывается.
    for(int n = 0; n < 10; ++n) {}
    int i;

    Под переменную n выделен участок стека, его значение к концу цикла равно 10 - и уже ненужная переменная n уничтожается, освобождая место в стеке.
    Под переменную i выделен участок стека, лежащее в нем значение не меняется. Это вполне может быть тот самый участок, который только что освободился, в нем записано 10 (С++ не выполняет ничего, что явно не указал программист - это оптимальный язык). Так что i вполне может равняться 10. Или нет.

    Подобные ситуации называются "неопределенным поведением".
    Программист на С++ обязан исключить их из своей программы.
    Ответ написан
    1 комментарий
  • Почему перемещение объявления и инициализации переменной на новую строчку кода влияет на результат работы программы?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    В этом коде есть важная ошибка. В циклах for нигде не задано начальное значение переменной i, поэтому она может иметь любое значение, её поведение неопределено. Например, она может выделиться там же, где была выделена предыдущая, поэтому i во втором цикле будет равна последнему значению в предыдущем, то есть 10, даже если в первом цикле повезло попасть на 0.

    Локальные переменные как правило выделяются в стеке, поэтому если между двумя for стоит определение ещё одной переменной, то она, вероятно, выделится на месте i. И поэтому новая переменная i попадёт в другую часть стека, где, если повезёт, будет 0.

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

    Решение простое: надо везде в циклах for указать начальное значение i, тогда всё станет нормально, и перестановка определения count перестанет создавать такие совсем не странные эффекты.
    Ответ написан
    3 комментария