Reputation: 2875
I'm new to c++ and came across this:
for (int i=0 ; i<500 ; i++) {
//to do
}
int i;
std::cin >> i;
UPDATE: Using visual studio 2010 (and the compiler it uses) the i outside the for loop has the value 500 AFTER the call to cin >> i; I am looking at the values using the Visual Studio debugger << (this is the problem - thanks Greg)
Now I expected
a) the int i; outside the for loop and the int i=0; to be different variables i.e. the for loop i to go out of scope once the braces close
b) once I realized that it wasn't going out of scope I wondered why it was not getting over-written by the cin.
I think b) is intentional (though I'm having trouble finding the page its on in Bjarne Stroustrup's book on c++) but I am sure it states in the same book that variables have scope within the braces they are enclosed in.
In most other languages I know when declaring variables in the for construct they are considered to be in the braces of the for loop but in c++ this doesn't seem to be the case.
Is this the case and is this specific to the for loop or are there any other cases where this happens (I can't think of any other but hey I'm new)
Thanks
Upvotes: 1
Views: 927
Reputation: 145279
Hm, lots of answers and even one selected as "solution".
But anyway, the problem with Visual C++ 10.0 (the compiler shipped with Visual Studio 2010) is that it defaults to it can be configured to pre-standard behavior, where the scope of a variable declared in a for
loop extended out the block the loop was placed in.
You want this option:
/Zc:forScope,wchar_t
which enables standard C++ for
-scope as well as built-in wchar_t
type, and you want this:
/GR
which enables RTTI (i.e. dynamic_cast
and typeid
).
Just to get as standard as you can you also want this linker option:
/entry:mainCRTStartup
to enable a C++ standard main
for GUI subsystem programs, and of course you want to enable exception handling, but as I recall for a Visual C++ project that's enabled by default (although not for the command line compiler).
Also, of course, you want to enable as many warnings as practical via /W4
, although that has nothing to do with standard-conformance.
But anyway, summing, the reason you get weird for
scopes is most probably due to the compiler and/or Visual Studio project defaulting having been set to the old pre-standard rules, and the option for that, is /Zc:forScope
.
Upvotes: 2
Reputation: 993173
In some situations, particularly in this case where you have two different variables in the same function with the same name, you can't always trust the debugger to give you correct information. If you're asking for the value of i
, the debugger might not know exactly which i
you are referring to. From what you have described, it sounds like the compiler has allocated two different memory locations for each different instance of i
.
I often use the principle When in doubt, print more out. If you use std::cout << i
, then you should see the actual value of i
that is in scope at the point where you print the output.
Upvotes: 3
Reputation: 1833
I assume it happens because 2nd i isn't intialized and compiler uses the same memory block for the second i. They are still different two variables. And yes the first i is scooped to the loop. Therefore it is undefined, you can't count on the second i to be 500.
for (int i=0 ; i<500 ; i++) {
//to do
}
int i=0; // initialize i
std::cin >> i;
Upvotes: 0
Reputation: 52294
Assuming conformance (and a compiler non conforming on that point would most probably have given a compilation error), your two i
are distinct. But nothing prevent the compiler to use the same memory location for both as their live time are also distinct, and thus having the second i
starting with the final value of the first as it isn't initialized is to be expected in that case.
The fact that cin >> i
doesn't allow you to enter a new value is unrelated with that. And you don't give enough information to do more than guessing a reason (my guess would be the stream is in an error state).
Upvotes: 0