scope

Storage Classes, Scope and Linkage

The scope of variables is limited to the block of code they are declared in. Any variables declared inside the body of a function are not accessible outside the function, and cannot therefore be referred to by name; these are the function’s local variables.

#include <iostream>

using namespace std;

void funcAB(){
    cout << "funcAB() called." << endl;
    
    int a = 42;
    int b = 73;

    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
}

int main(void){

    int c = 1138;

    cout << "c = " << c << endl;
    cout << "cannot refer to a or b in the main() function." << endl;

    funcAB();

}

As we seen, global identifiers are available to a function or block, as long as it is declared before the function or code block, and its identifier, i.e. its name, is different than any function or local variable identifiers.

The extern keyword can be employed to make the use of a global variable explicit; this enables a function to access a global variable that has been declared after the definition of a function.

#include <iostream>

using namespace std;


void funcSetDoubles();
void funcPrintDoubles();

void funcSetDoubles(){
    extern double dare;
    extern double trouble;
    dare = 2.41;
    trouble = 103.5075;
}

void funcPrintDoubles(){
    extern double dare;
    extern double trouble;

    cout << dare << endl;
    cout << trouble << endl;
}

double dare;
double trouble;


int main(void){

    dare = 390.315;
    trouble = 1.05;

    funcPrintDoubles();
    funcSetDoubles();
    funcPrintDoubles();

    return 0;
    
}



It is possible to declare a function away from its definition. A function declaration is just like the header of a function definition, although including the parameters’ names is optional. A function declaration introduces an identifier into the program.

The storage class of memory item is what type of storage is used for it. Automatic storage is on the program’s stack and is where function variables are allocated and stored. Static storage is where data is stored for the duration of the program’s lifetime. The heap is the section of memory where items allocated with new and new[] are stored.

Global variables are static variables, they are allocated and remain “in play” for the duration of the program. Variables declared within a block are automatic variables, they remain in scope only for the duration of the code block. We can create static variables inside a block by using the reserved keyword static.

#include <iostream>

using namespace std;

void funcTest(void);

int z = 0;  

int main(void){

    int y = 3000;
    extern int z;

    for(int i = 0; i < 10; i++){
        funcTest();
        y += i;
        z++;
        cout << "In main(): ";
        cout << "y = " << y << " z = " << z << endl;
    }
    return 0;

}

void funcTest(void){
    cout << "Inside funcTest(): ";

    static int x = 0;
    extern int z;

    int y = 3;
    z++;
    x = z + y;
    cout << "z = " << z << " y = " << y << " x = " << x << endl;
}

Remember, automatic storage allocates memory for the item at block entry and deallocates it at block exit. Static storage is allocated as long as the program executes.

A C++ program consists of a collection of files. A file, like a function, is a unit of scope, just as if it were enclosed in curly braces. Any variables declared in  file but outside of any function are global variables, they are in scope in any functions declared later in the file.

#include <iostream>

int x;
int y;

using namespace std;

void funcChangeX(int n){
    x += n;
}

void funcChangeY(int n){
    y -= n;
}

void funcShowXAndY(){
    cout << "x = " << x << " and y = " << y << endl;
}

int main(void){

    x = 1701;
    y = 404;

    cout << "x = " << x << endl;
    cout << "y = " << y << endl;

    funcChangeX(1999);

    funcChangeY(47);

    funcShowXAndY();    


    return 0;

}

To make sure that the necessary identifiers are in scope in all the files they are needed in, we must include the declarations in each file with the #include preprocessor statement. Library header files are included with angle brackets, and custom header files are included with quotation marks.

The linker takes the declarations to the appropriate definitions, and combines the compiled files of the program, along with the libraries it uses, into a single executable binary.