Welcome to the universe of C++!
For your question, the answer lay in a concept called 'Point-of-declaration'.
>>int x = 1;
>>{ int x = x; } // garbage value of x
From Section:-3.3.1.1 (C++ Standard Draft)
The point of declaration for a name is immediately after its complete declarator and before its initializer (if any), except as noted below.
int x = 12;
{ int x = x; }
Here; the 'operator =' is the initializer. You can say that the point-of-declaration for 'x' is not yet reached, so the value of 'x' is indeterminate.
>>int const arr = 3;
>>{ int arr[arr]; } // i am told this is perfectly valid and declares an array of 3 ints !!
Why?
From Section:-3.3.1.4 (C++ Standard Draft)
A nonlocal name remains visible up to the point of declaration of the local name that hides it. Here the point of declaration is reached at ';' character. So the earlier visible value of 'arr' is used i.e. = 3.
Also, you may wish to know that the following is valid :-
const int e = 2;
{ enum { e = e }; } // enum e = 2
From Section:-Chapter-3.3.1.4 (C++ Standard Draft):-
The point of declaration for an enumerator is immediately after its enumerator-definition.
But, don't do this
const int Spades = 1, Clubs = 2, Hearts = 3, Diamonds = 4;
enum Suits
{
Spades = Spades, // error
Clubs, // error
Hearts, // error
Diamonds // error
};
Why? Because enumerators are exported to the enclosing scope of the enumeration. In the above example, the enumerators Spades, Clubs, Hearts, and Diamonds are declared. Because the enumerators are exported to the enclosing scope, they are considered to have global scope. The identifiers in the example are already defined in global scope. So its an error.
For additional details and pitfalls ( :-) ), read-up on section 3.3 'Declarative regions and scopes' from the Draft C++ Standard, if interested you can get hold of the pdf from here(http://www.research.att.com/~bs/SC22-N-4411.pdf).