Подтвердить что ты не робот

С++ переопределение переменной счетчика циклов непоследовательное поведение?

Я делаю С++ в Visual Studio 2010 и обнаружил нечетное поведение. Короче говоря, я обнаружил, что это не скомпилируется:

for (int i = 0; i < 10; i++)
{
    int i = 11;
}

Это кажется правильным, поскольку переменная я уже объявлена ​​в заголовке цикла цикла.

Теперь, однако, если я вставляю другой цикл for перед повторным объявлением i, то внезапно компилятор, intellisense и т.д. код корректен - не дает никаких реальных предупреждений (Tried warnings level 3 и four (/W3 и /w 4)). Таким образом, это будет скомпилировано и запущено:

for (int i = 0; i < 10; i++)
{
    for(int j = 0; j < 5; j++)
    {
    }

    int i = 11;
}

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

Спасибо заранее!

EDIT: Вау, спасибо всем за все ответы и демонстрации - Ты потрясающий!:) Этот образец, разоблачающий ошибку, перешел мне в голову, я просто предположил, что MS уже заметила бы такую ​​вещь и зафиксировала ее... по крайней мере, в VS2013.

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

Спасибо всем!

Первая часть кода

Второй фрагмент кода

Кредит для демонстраций: @Mark Garcia

4b9b3361

Ответ 1

В соответствии со стандартной спецификацией:

1... имена, объявленные в for-init-statement, находятся в той же декларативной области, что и объявленные в условии

3 Если for-init-statement является объявлением, область имени (имен) объявляется до конца for-statement. [§6.5.3]

и

4Имена, объявленные в for-init-statement, for-range-declaration и в условии if, while, for и switch, являются локальными для оператора if, while, for или switch (включая управляемый оператор), и не должны быть переоформлены в последующем условии этого утверждения или в самом внешнем блоке (или для оператора if любого из самых отдаленных блоков) контролируемого оператора [§3.3.3]

Поведение MSVС++ 2010 не является стандартным и это ошибка.

Ответ 2

когда вы делаете что-то вроде:

 for (int i = 0; i < 10; i++)
    {
     //some code
    }

вы объявляете переменную я и ограничиваете ее область видимости для кода. Так что это будет видно только внутри цикла for. Имея это в виду, ваш первый фрагмент кода переопределяет переменную i;

for (int i = 0; i < 10; i++)
 {
      int i;
 }

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

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