Broad Network


Basics of C++ Identifier Scope

C++ Taking the Bull by the Horns – Part 21

Forward: In this part of the series, we look at what is called identifier scope.

By: Chrysanthus Date Published: 22 Aug 2012

Introduction

This is part 21 of my series, C++ Taking the Bull by the Horns. In this part of the series, we look at what is called identifier scope. A block is a set of statements enclosed in curly braces, which are { and }. The question here is: if an identifier is defined outside a block will it be seen in the block? On the other hand, if it is defined inside the block, will it be seen outside the block? Blocks do not occur arbitrarily in code. There are certain constructs that have blocks.  The following constructs have blocks: if, while, for, and function. We have seen all of these constructs. There are other blocks we are still to see, later.

For the rest of this tutorial, we look at the if, for and function constructs and how identifier scope is applied to them.

Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.

The if Construct and Identifier Scope
Read and try the following code:

#include <iostream>
using namespace std;

int main()
    {
        int myInt = 40;

        if (25 == 25)
            {
                cout << myInt;
                int herInt = 50;
            }
        
        //cout << herInt;

        return 0;
    }

The if-condition is “if 25 is equal to 25”. Now this condition will always return true, and so the if-block will always be executed. Outside the if-block, the identifier, myInt is defined and assigned the value, 40. Inside the if-block there is a statement to print (display) myInt. This identifier was defined outside the if-block; if it is seen inside the block, it will be printed. If you tried the code you would have noticed that the value of myInt was printed.

Now, inside the block, a new identifier, herInt was defined and had a value assigned to it. Outside the block, there is a comment. This comment is actually a statement preceded by the comment denotation, //. Because of this preceding sign, the statement is not executed. If you remove the comment denotation and re-try the code, the following explanation will follow:

The herInt identifier is defined inside the if-block. Now, if it is seen outside the block, then the “last” statement (without the comment denotation) would print its value. Remove the // symbol and try the code if you have not already done so, and note that the last print statement would not work (the program will not even be executed), and you would receive an error message or error messages at compile time.

The Function Construct and Identifier Scope
The following code has been written similar to the above, but the function is outside the main function; the identifiers and test (print) statement have been written in a similar way.

Read and try the following code:

#include <iostream>
using namespace std;

int myInt = 40;

void myFn()
    {
        cout << myInt;
         int herInt = 50;
    }

    int main()
        {
            myFn();
   
            //cout << herInt;
    
            return 0;
        }

You should have tried the code. Note that an identifier defined outside the function block (but not in another block) is seen inside the function block.

Now remove the comment denotation in the “last” line and try the code again; you will receive an error message at compile time, because an identifier defined inside a function block cannot be seen outside the function block.

The for Construct and Identifier Scope
The following code has been written similar to the above (everything is in the main block); the identifiers and test (print) statements have been written in a similar way.

Read and try the following code:

#include <iostream>
using namespace std;

int main()
    {
        int myInt = 40;

        int i=0;
        for (i=0; i< 3; ++i)
            {
                cout << myInt; cout << "\n";
                int herInt = 50;
            }

        //cout << herInt;

        return 0;
    }

You should have tried the code. Note that identifier defined outside the for-block is seen inside the for-block. In this case the value of the identifier is printed 3 times.

Now remove the comment denotation in the “last” line and try the code again; you will receive an error message at compile time, because an identifier declared inside the for block cannot be seen outside the for-block.

Deduction
Blocks exist with different constructs. An identifier declared outside blocks can be seen inside blocks. An identifier declared inside a block cannot be seen outside the block.

The principles outlined in this tutorial are applicable to initializations as well. Recall that initialization is definition and assignment. We actually have assignments in the above cases and not just definitions.

File Scope
If an identifier is not defined inside any block, not even inside the main function block, then that identifier is said to have file scope. We saw an example above when we were dealing with the function construct (myInt).

Block Scope
An identifier defined inside a block can be seen only inside that block. Such an identifier is said to have block scope, or local scope.

A Block inside a Block
If an identifier is defined inside a block, can it be seen inside a nested block? The answer is Yes and we have already come across this without being conscious of it. Consider the case of the if-construct above. The main function has a block. The if-block is inside the main function. So the if-block is nested inside the block of the main function. Above, the identifier, myInt, defined inside the main function block but not inside the if-block, was seen inside the if-block. So an identifier defined inside a block, can be seen inside a nested block. Note: a file scope identifier can be seen inside any block, including nested blocks.

Question: Can you have one file scope identifier and one block scope identifier with the same name and object type? Yes, you can. Under that condition, in the block scope, the identifier in the block scope takes precedence.

Global Scope
A file scope identifier is an identifier defined in a file that is not in any block. Well, we now know that there are include files as indicated in the following code:

#include <fileA>
#include <fileB>

int fScopeID;

int main()
    {
        //some statements
        return 0;
    }

Above, fileA is a file. fileB is also a file. You also have the main file with the include directives. So, the ultimate program above consists of 3 files. An include directive collects the content of a file from an include directory and places the content in the main file at the position where the include directive is. The content brought, replaces the include directive. The content brought is normally made up of many statements. When the content comes, the main file becomes longer and its length may have a considerable increase, because the statements (declarations) from the include file may be many.

If you look at the content of any of the include files, you would find identifiers with file scope. Assume that in the resulting file from the above code, fileA has file scope identifiers, fileB has file scope identifiers and the main file has file scope identifiers (fScopeID for example). The resulting file from the above code is one very long file. Do we say the identifiers of file scope for each file have now become file scope identifiers for the resulting file? This problem is solved with another vocabulary that is Global Scope.

In the resulting file, the identifiers for file scope are called global scope identifiers.

When we talk about scope and identifiers, we are not only referring to identifiers of fundamental object types, we are referring to any identifier: identifiers of fundamental object types, identifiers of derived object types and identifiers of classes (see later).

Note: An object declared in a scope, is destroyed at the end of the scope.

That is what I have prepared, for this tutorial. Let us stop here and continue in the next part of the series.

Chrys

Related Courses

C++ Course
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
NEXT

Comments

Become the Writer's Fan
Send the Writer a Message