Name Visibility

In C++, the position where a variable is declared affects where it can be used.

Scopes

A scope is the region of a program where a name can be used and can be accessed directly by its name. We say the name is visible in that scope. Most scopes are the areas surrounded by curly brackets {}. The area outside any scope is called a global scope. Any other area is called a local scope.

#include<iostream>
using namespace std;

// global scope
int x = 5;

int main() {
    // local scope 1
    int y = 4
    
    for (int i = 0 ; i < 5 ; i++) {
        // local scope 2
        int z = 20;
        if (i % 2 == 0) {
            // local scope 3
            cout << z + x << ' ' << z + y << endl;
        }
        else {
            // local scope 4
            cout << z - y << ' ' << z - x << endl;
        }
    }
}

In this example we have a global scope and 4 local scopes. Note that the scope 1 extend through the whole main function, the scope 2 is the region inside the for loop, and scopes 3 and 4 are the areas inside each of the if and else blocks repsectively.

Where is a Variable Visible?

Globally initialized variables (also called global variables) are visible and can be used in all scopes after their intialization. Locally initialized variables (also called local variables) are visible only within the scope they are declared in. This includes the scopes nested within their scopes, i.e. inner scopes.

Looking at the previouse example this is the visiblility of each x, y, and z:

Variable name Declared in Visible in
x Global scope All scopes
y Scope 1 (inside main()) All local scopes
i for loop that starts the scope 2 Scopes 2, 3, and 4
z Scope 2 (inside for) Scopes 2, 3, and 4

Note that variables declared within for loop initialization belong to the scope of the body of the for loop, even though the initialization is before the curly braces.

Warning

Using a variable outside its scope will lead to a compilation error.

Naming Within a Scope

In a single scope a name can only represent one variable

#include<iostream>
using namespace std;

int main() {
    int x = 5;
    string x = "Hello world"; // compilation error because x is declared twice
}

Even though we said that a name can only represent one variable, it’s ok if we declare a variable in a scope and then declare another variable with the same name in an inner scope. In that case, when we use this name we’ll be using the inner variable.

#include<iostream>
using namespace std;

int x = 5;

int main() {
    int x; // fine because we're in an inner scope of the global scope
    cin >> x;
    
    if (x == 5) {
        string x = "Hello world"; // fine because we're again in another inner scope
        cout << x << endl;
    }
    else {
        cout << x << endl;
    }
}