Let's simplify for a moment:
int x = 1;
void f() {
int x = 3;
std::cout << x << '\n';
}
Here, the local x hides the global x, and the output statement writes out the value of the local x, namely, 3. Simple enough.
If you need to use the global x inside that function you can name it with a scope qualifier:
int x = 1;
void f() {
int x = 3;
std::cout << ::x << '\n'; // note the :: in front of x
}
Because of the scope qualifiers, ::x refers to the global x (that's what :: means), so the output statement writes out the value of the global x, namely, 1.
Now the weird case:
int x = 1;
void f() {
int x = x;
std::cout << x << '\n';
}
Again, the name x hides the global x, so int x = x; initializes the newly-created x with its own value. Which doesn't make sense. And as the comments to the question so helpfully pointed out, the result is undefined behavior.
But since the goal is to initialize the local x with the value of the global x, the answer should now be obvious:
int x = 1;
void f() {
int x = ::x;
std::cout << x << '\n';
++x;
std::cout << x << '\n';
std::cout << ::x << '\n';
}
Now the local x gets initialized with the value of the global x, and the first output statement writes out the value of the local x, namely 1. Just for completeness, after the modification of the value of the local x, the second output statement writes out the new value of the local x, namely 2. The third output statement writes out the value of the global x, which is still 1.
If you're really into confusing yourself, you can hide a name with a nested scope, like this:
void f() {
int x = 1;
{
int x = 2;
// ??
}
}
Here, at the line marked // ??, there's no syntax for getting at the x in the outer scope.