In this declaration
int x = x;
the point of declaration of the identifier x
is after the complete definition of the declarator that is x
is already visible before the assignment sign =
and hides the variable with the same name declared in the outer block scope..
And you have that x
that is not initialized is assigned to itself. As result it has an indeterminate value.
You can imagine it the following way
int x;
x = x;
Exactly the same example exists in the C++ Standard (3.3.2 Point of declaration)
1 The point of declaration for a name is immediately after its
complete declarator (Clause 8) and before its initializer (if any),
except as noted below. [ Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value.
—end example ]
In the C Standard there is written (6.2.1 Scopes of identifiers)
7 Structure, union, and enumeration tags have scope that begins just
after the appearance of the tag in a type specifier that declares the
tag. Each enumeration constant has scope that begins just after the
appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of
its declarator.
Pay attention to the definition of enumerators. The rule for enumerators is different.
This program is well-formed and the enumerator x
will be initialized by the variable x
declared in the outer scope (while the enumerator y
will be initialized by the preceding enumerator x
).
#include <iostream>
int main()
{
const int x = 10;
{
enum E { x = x + 1, y = x };
std::cout << "E::x = " << x << ", E::y = " << y << std::endl;
}
std::cout << "x = " << x << std::endl;
}
The program output is
E::x = 11, E::y = 11
x = 10