Is there any way to access a local variable in outer scope in C++?

Just out of curiosity: if I have nested scopes, like in this sample C++ code

using namespace std;

int v = 1; // global

int main (void)
{
    int v = 2; // local
    {
        int v = 3; // within subscope
        cout << "subscope: " << v << endl;
        // cout << "local: " << v << endl; 
        cout << "global: " << ::v << endl;
    }
    cout << "local: " << v << endl;

    cout << "global: " << ::v << endl;

}

Is there any way to access the variable v with the value 2 from the "intermediate" scope (neither global nor local)?


You can declare a new reference as an alias like so

int main (void)
{
    int v = 2; // local 
    int &vlocal = v;
    {
        int v = 3; // within subscope
        cout << "local: " << vlocal  << endl; 
    }
}

But I would avoid this practice this altogether. I have spent hours debugging such a construct because a variable was displayed in debugger as changed because of scope and I couldn't figure out how it got changed.


The answer is No You cannot.
A variable in local scope shadows the variable in global scope and the language provides a way for accessing the global variable by using qualified names of the global like you did. But C++ as an language does not provide anyway to access the intermediate scoped variable.

Considering it would have to be allowed it would require a lot of complex handling, Imagine of the situation with n number of scopes(could very well be infinite) and handling of those.

You are better off renaming your intermediate variables and using those that would be more logical and easy to maintain.


There are two types of scope resolution operators in C++ - unary scope and a class scope. There is no function scope or "any particular parent scope" resolution operators. That makes it impossible to solve your problem, as it is, in general because you cannot refer to anonymous scopes. However, you can either create an alias, rename variables, or make this a part of the class, which of course implies a code change. This is the closest I can get you without renaming in this particular case:

#include <iostream>

using namespace std;

int v = 1; // global

class Program
{
    static int v; // local

public:
    static int main ()
    {
        int v = 3; // within subscope
        cout << "subscope: " << v << endl;
        cout << "local: " << Program::v << endl; 
        cout << "global: " << ::v << endl;
    }
};

int Program::v = 2;

int main ()
{
    return Program::main ();
}

There are other ways, like making sure that variables are not optimized out and are on stack, then you can work with stack directly to get the value of the variable you want, but let's not go that way.

Hope it helps!


You could fake it like this:

#include <iostream>
using namespace std;
int v = 1;

int main()
{
        int v = 2;
        {
                int &rv = v; // create a reference
                int v = 3; // then shadow it

                cout << "subscope: " << v << endl;
                cout << "local: " << rv << endl;
                cout << "global: " << ::v << endl;
        }
        cout << "local: " << v << endl;

        cout << "global: " << ::v << endl;

        return 0;
}

Interestingly this compiles on cygwin g++ but segfaults if you try to run it:

#include <iostream>
using namespace std;
int v = 1;

int main()
{
        int v = 2;
        {
                int &v = v;
                cout << "subscope: " << v << endl;
                // cout << "local: " << v << endl; 
                cout << "global: " << ::v << endl;
        }
        cout << "local: " << v << endl;

        cout << "global: " << ::v << endl;

        return 0;
}