Search code examples
c++11scopes

C++ 11- scopes & global variables


How can I reach global variables from inner scopes, given the following code sample, how can I reach the global string X from the main function and from the most inner scope as well, also is the most inner scope is accessible once we quit it to the main scope or other scope?

#include <iostream>
#include <string>
std::string x = "global";
int counter = 1;

int main()
{
    std::cout <<counter ++ << " " << x << std::endl;
    std::string x = "main scope";
    std::cout <<counter ++ << " "  << x << std::endl;
    {
        std::cout <<counter ++ << " " << x << std::endl;
        std::string x = "inner scope";
        std::cout <<counter ++ << " " << x << std::endl;
    }
    std::cout <<counter++ << " "  << x << std::endl;
}

the cout currently is:

1 global
2 main scope
3 main scope
4 inner scope
5 main scope

Solution

  • Global scope can be reached by using ::x, as per:

    #include <iostream>
    #include <string>
    
    std::string x = "global";
    int counter = 1;
    
    int main()
    {
        std::cout << counter++ << " " << x << std::endl;
        std::string x = "main scope";
        std::cout << "  " << ::x << std::endl;
        std::cout << counter++ << " "  << x << std::endl;
        {
            std::cout << "  " << ::x << std::endl;
            std::cout << counter++ << " " << x << std::endl;
            std::string x = "inner scope";
            std::cout << "  " << ::x << std::endl;
            std::cout << counter++ << " " << x << std::endl;
        }
        std::cout << "  " << ::x << std::endl;
        std::cout << counter++ << " "  << x << std::endl;
    }
    

    which gives you:

    1 global
      global
    2 main scope
      global
    3 main scope
      global
    4 inner scope
      global
    5 main scope
    

    The hard bit is actually getting to the intermediate scopes, such as main scope when you're withing the inner scope.

    One way to do that is with references:

    #include <iostream>
    #include <string>
    
    std::string x = "outer";
    
    int main()
    {
        std::cout << "1a " << x << "\n\n";
    
        std::string x = "middle";
        std::cout << "2a " << ::x << '\n';
        std::cout << "2b " << x << "\n\n";
    
        {
            std::string &midx = x;  // make ref to middle x.
            std::string x = "inner";  // hides middle x.
            std::cout << "3a " << ::x << '\n';
            std::cout << "3b " << midx << '\n';  // get middle x via ref.
            std::cout << "3c " << x << "\n\n";
        }
    }
    

    which gives:

    1a outer
    
    2a outer
    2b middle
    
    3a outer
    3b middle
    3c inner
    

    But, as good advice, you'll find you won't have anywhere near as many problems if you:

    • name your variables a little more intelligently so as to avoid clashes; and
    • avoid global variables like the plague :-)

    And, as for the variables in inner scopes, they cease to be available once you leave that scope, even with a reference (you can copy them to a variable with an larger scope but that's not the same as accessing the inner-scoped variable).