I'm working my way through Accelerated C++ right now, and I've encountered a fundamental lack of understanding regarding scope and code blocks on my part.
There is an exercise at the end of chapter 1 that wants you to decide whether this code is will run:
#include <iostream>
#include <string>
int main()
{
{
const std::string s = "a string";
std::cout << s << std::endl;
{
const std::string s = "another string";
std::cout << s << std::endl;
}
}
return 0;
}
I was sure it wouldn't, but it does. My hobby programming experience was that variables declared in a block are available to other blocks contained within it, but not those outside of it.
And that must be at least half-true, since removing the second declaration of s will output "a string" twice, giving me the impression that s as declared in the second block is also present in the third block.
I also tried removing the braces of the third block entirely, resulting in the compilation error I expected in the first place. But how is that different from declaring a constant that already exists in the scope of the third block? Does the declaration of a constant only carry over to a smaller scope if there is no second declaration in that smaller scope?
I've gone through everything in the book up until this point again to see if I missed something, but I can't find any information on how variable and const declarations are affected by curly braces.
This doesn't just apply to constants though, that doesn't matter.
You are introducing another scope, where the variable
s
has not been defined, so it is perfectly legal to define one. If you remove one, you'll get a redefinition error, because you already have ans
in the same scope.Not really. Your second
s
is shadowing the first one. Technically, both of them exist, but you have no way of accessing the first one. Sometimes you do, with the help of the scope resolution operator, but in your case, no.Curly braces in general introduce a new scope (although there are some exceptions). As long as a variable with a given name is not defined in the current scope, you can define it. It doesn't matter if there is a variable with the same name in a scope outside of it, but your compiler will likely warn you about it.