2013-11-25 11 views
31

Robię C++ w Visual Studio 2010 i znalazłem dziwne zachowanie. Aby długie opowiadanie, stwierdziliśmy, że nie będzie to skompilować:C++ redeclaration niespójne zachowanie zmiennej pętli count?

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

Wydaje się słuszne, gdyż zmienna i jest już zadeklarowana w nagłówku pętli for.

Teraz jednak, jeśli wstawię inną pętlę for przed ponowną deklaracją i, to nagle kompilator, intellisense itp thiks kod jest poprawny - nie dając żadnych prawdziwych ostrzeżeń (wypróbowane ostrzeżenia na poziomie 3 i 4 (/ W3 i/w4)). Tak, robi to rzeczywiście skompilować i uruchomić:

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

    int i = 11; 
} 

Osobiście uważam, że to dziwne, że insering innego dla pętli legitimates skądinąd sam scenariusz kodu. Wszelkiego rodzaju ducha, który może mi powiedzieć, co tu widzę?

Z góry dziękuję!

EDYTOWANIE: Wow, dziękuję wszystkim za wszystkie odpowiedzi i prezentacje - Jesteś niesamowity! :) Ta próbka odsłaniająca błąd przeszła mi przez myśl, po prostu założyłem, że MS zauważyłoby coś takiego i naprawiło to ... przynajmniej w VS2013.

Próbowano zmienić ustawienia optymalizacji zgodnie z sugestią, ale nie miało to żadnego znaczenia.

Dziękuję wszystkim!

First piece of code

Second piece of code

Kredyt dla dema: @Mark Garcia

+1

Czy to kompilator, czy intellisense? –

+2

[Pierwszy fragment kodu] (http://rextester.com/ORRMS33867), [drugi fragment kodu] (http://rextester.com/ESBFG91953). –

+0

Kompilacja kompilatora @LuchianGrigore. VS2012 odrzuca także pierwszy fragment i akceptuje drugi. – Mysticial

Odpowiedz

19

Według standardowej specyfikacji:

... Nazwy zadeklarowane w instrukcji dla instrukcji init znajdują się w tym samym regionie deklaratywnym, co deklarowane w warunku:

Jeśli deklaracja dlainicjowania jest deklaracją, zakres zadeklarowanych nazw rozciąga się na koniec instrukcji for. [§6.5.3]

i

nazw zadeklarowanych w for-init-deklaracji, o zasięgu-deklaracji, w warunku if, while, do i instrukcje switch są lokalne dla instrukcji if, while, lub switch (łącznie z instrukcją kontrolowaną) i nie powinny być ponownie zadeklarowane w kolejnym warunku tego polecenia, ani w najbardziej oddalonym bloku (lub, w przypadku instrukcji if, dowolnym z najbardziej oddalonych bloków) kontrolowanego wyciągu [§3.3.3]

Zachowanie MSVC++ 2010 nie jest standardem i to błąd.

+0

Zobacz także [tę odpowiedź] (http://stackoverflow.com/a/12351531/2513200) na nieco powiązane pytanie (które zgadza się z Twoją interpretacją) – Hulk

0

kiedy robisz coś takiego:

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

jesteś deklarując zmienną I i ograniczając jego zakres do dla kodu bloku. Będzie to widoczne tylko w pętli for. Mając to na uwadze, twój pierwszy fragment kodu na nowo definiuje zmienną i;

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

kompilator narzeka na redefinicję, ponieważ masz teraz 2 zmienne o tej samej nazwie, tym samym typie danych i tym samym zasięgu.

Jeśli chodzi o przyczynę kompilacji drugiego fragmentu kodu - błąd kompilatora. To zależy wyłącznie od implementacji kompilatora; jeśli zmienisz poziom optymalizacji, może się on już nie pojawiać.