SCOPE


1. SCOPE RULES

Scope rules govern the lifetime and visibility of data items (i.e. the parts of a program where they can be used).

[A] A data item is visible from where it is declared to the end of the block in which the declaration is made.

For example in the following procedure the constants X_ITEM and Y_ITEM are visible from when they are declared till the end of the procedure. This is why X_ITEM can be used in the declaration of Y_ITEM (we could not do the reverse, or at least not without first reordering the declarations).

procedure SUM_AND_PROD is
    X_ITEM : constant := 2;
    Y_ITEM : constant := X_ITEM*2;
begin
    PUT(X_ITEM+Y_ITEM);
    NEW_LINE;
    PUT(X_ITEM*Y_ITEM);
    NEW_LINE;
end SUM_AND_PROD;

[B] A data item declared within a block cannot be seen from outside that block, and is referred to as local data item, i.e. local to a block.

Consider the following example program (Nesting illustrated in diagram to right):

NESTING DIAGRAM
with CS_IO;
use CI_IO;

procedure SUM_AND_PROD is
    X_ITEM : constant := 2;
    Y_ITEM : constant := X_ITEM*2;

----------------------------------------------------
    procedure SUM(P_ITEM, Q_ITEM : INTEGER) is
        TOTAL : INTEGER ;
    begin
        TOTAL := P_ITEM + Q_ITEM;
        PUT(TOTAL);
        NEW_LINE;
    end SUM;
----------------------------------------------------
    procedure PRODUCT(S_ITEM, T_ITEM : INTEGER) is
        PROD : INTEGER ;
    begin
        PROD := S_ITEM * T_ITEM;
        PUT(PROD);
        NEW_LINE;
    end PRODUCT;
----------------------------------------------------

begin
    SUM(X_ITEM,Y_ITEM);
    PRODUCT(X_ITEM,Y_ITEM);
end SUM_AND_PROD;

The data items P_ITEM, Q_ITEM and TOTAL are local to the SUM procedure (block), while data items S_ITEM, T_ITEM and PROD are local to the PRODUCT procedure (block).

[C] Anything declared in a block is also visible in all enclosed blocks.

Thus in the following example program (nesting given ti the right) the data item ANSWER is visible to the two enclosed blocks (SUM and product).

NESTING DIAGRAM
with CS_IO;
use CI_IO;

procedure SUM_AND_PROD is
    X_ITEM : constant := 2;
    Y_ITEM : constant := X_ITEM*2;

----------------------------------------------------
    procedure SUM_AND_PRODUCT(P_ITEM,
                Q_ITEM: INTEGER) is
        ANSWER : INTEGER;
    --------------------------------------------
        procedure SUM(A_ITEM,B_ITEM: INTEGER) is
        begin
            ANSWER := A_ITEM + B_ITEM;
        end SUM;
    --------------------------------------------
        procedure PRODUCT(C_ITEM,D_ITEM: INTEGER) is
        begin
            ANSWER := C_ITEM * D_ITEM;
        end PRODUCT;
    --------------------------------------------
    begin
        SUM(P_ITEM,Q_ITEM);
        PUT(ANSWER);
        NEW_LINE;
        PRODUCT(P_ITEM,Q_ITEM);
        PUT(ANSWER);
        NEW_LINE;
    end SUM_AND_PRODUCT;
----------------------------------------------------

begin
    SUM_AND_PRODUCT(X_ITEM,Y_ITEM);
end SUM_AND_PROD;

Global data items (items which are required to be visible from anywhere in a program) must be declared within the outermost block, i.e. level 1 or the global level. Note that where ever possible use of global data items should be avoided as the values associated with these items can easily be altered erroneously.

[D] Several data items with the same name cannot be used in the same block, however several items with the same name can be declared in "different" blocks.

In this case the declared items have nothing to do with one another (other than sharing the same name). For example:

NESTING DIAGRAM
with CS_IO;
use CI_IO;

procedure SUM_AND_PROD is
    X_ITEM : constant := 2;
    Y_ITEM : constant := X_ITEM*2;

----------------------------------------------------
    procedure SUM(P_ITEM, Q_ITEM : INTEGER) is
        TOTAL : INTEGER;
    begin
        TOTAL := P_ITEM + Q_ITEM;
        PUT(TOTAL);
        NEW_LINE;
    end SUM;
----------------------------------------------------
    procedure PRODUCT(P_ITEM, Q_ITEM : INTEGER) is
        TOTAL : INTEGER;
    begin
        TOTAL := P_ITEM * Q_ITEM;
        PUT(TOTAL);
        NEW_LINE;
    end PRODUCT;
----------------------------------------------------

begin
    SUM(X_ITEM,Y_ITEM);
    PRODUCT(X_ITEM,Y_ITEM);
end SUM_AND_PROD;

Here the repeated declarations of the data items TOTAL P_ITEM and Q_ITEM define data items that are completely independent (despite the shared name).

[E] Where a name is used in a block and reused in a sub-block nested within it, the sub -block declaration will override the super-block declaration during the life time of the sub-block.

This is referred to as occlusion. The identifier which is hidden because of the inner declaration is said to be occluded. This is the case in the following example:

NESTING DIAGRAM
with CS_IO;
use CI_IO;

procedure SUM_AND_PROD is
    X_ITEM : constant := 2;
    Y_ITEM : constant := X_ITEM*2;

----------------------------------------------------
    procedure SUM(P_ITEM, Q_ITEM : INTEGER) is
        X_ITEM : INTEGER;
    begin
        X_ITEM := P_ITEM + Q_ITEM;
        PUT(X_ITEM);
        NEW_LINE;
    end SUM;
----------------------------------------------------
    procedure PRODUCT(X_ITEM, Y_ITEM : INTEGER) is
        PROD : INTEGER;
    begin
        PROD := X_ITEM * Y_ITEM;
        PUT(PROD);
        NEW_LINE;
    end PRODUCT;
----------------------------------------------------

begin
    SUM(X_ITEM,Y_ITEM);
    PRODUCT(X_ITEM,Y_ITEM);
end SUM_AND_PROD;

Here the global data item, X_ITEM is occluded in the SUM and PRODUCT procedures. The data item Y_ITEM is occluded in the PRODUCT procedure in a similar way.


2. ORDER OF PROCEDURE DECLARATIONS IN BLOCK STRUCTURED LANGUAGES

In block structured languages, such as Ada, the order in which procedures and functions are declared also effects their visibility (which procedure or function can be used by which other procedure or function). Ada requires that any use of an identifier must be preceded by its declaration. Thus if two procedures are declared at the same level, their order of declaration will dictate "who can call whom". The procedure currently being declared cannot "see" any following procedures.

Note also that a following procedure cannot see a procedure or function nested within a previous procedure or function. Consider the following piece of code (nesting given to right):

NESTING DIAGRAM
with CS_IO;
use CS_IO;

procedure SUM_AND_PROD is
    X_ITEM : constant := 2;
    Y_ITEM : constant := X_ITEM*2;
    --------------------------------------------------------
    procedure SUM(P_ITEM, Q_ITEM : INTEGER) is
        TOTAL : INTEGER ;
        ------------------------------------------------
        procedure SUMMATION(R_ITEM, S_ITEM : INTEGER)
                is
        begin
            TOTAL := R_ITEM + S_ITEM;
            PUT(TOTAL);
            NEW_LINE;
        end SUMMATION;
        ------------------------------------------------
    begin
        SUMMATION(P_ITEM, Q_ITEM);
    end SUM;

    --------------------------------------------------------
    procedure PRODUCT(P_ITEM, Q_ITEM : INTEGER) is
    begin
        PUT(P_ITEM * Q_ITEM);
        NEW_LINE;
        SUM(P_ITEM, Q_ITEM);
    end PRODUCT;
    --------------------------------------------------------

begin
    PRODUCT(X_ITEM,Y_ITEM);
end SUM_AND_PROD;

Here the procedure PRODUCT can see the procedure SUM because it is at the same level and declared before it. The procedure PRODUCT cannot see SUMMATION because it is nested within the procedure SUM. Conversely the procedure SUM cannot see the procedure PRODUCT because it is declared after it (despite being at the same level), however it can see the procedure SUMMATION because it is nested within it.


3. SCOPE EXAMPLE

Consider the following Ada program

ADA NESTING DIAGRAM
-- SCOPE TEST PROGRAM
-- 21 April 1996
-- Frans Coenen
-- Dept Computer Science, University of Liverpool

with CS_IO;
use CS_IO;

procedure PROC_1 is
     A_VALUE: INTEGER := 1;
     B_VALUE: INTEGER := 2*A_VALUE;

----------------------------------------------------
-- PROCEDURE 2
     procedure PROC_2 (X_VALUE: INTEGER) is
          A_VALUE: FLOAT:= 22.22;
    --------------------------------------------
    -- PROCEDURE 3
        procedure PROC_3 (C_VALUE: FLOAT) is
            X_VALUE: FLOAT := 22.22;
        begin
            PUT("In PROC_3: A_VALUE = ");
            PUT(A_VALUE, FORE=>2, AFT=>2, EXP=>0);
            NEW_LINE;
            PUT("In PROC_3: B_VALUE = ");
            PUT(B_VALUE);
            NEW_LINE;
            PUT("In PROC_3: C_VALUE = ");
            PUT(C_VALUE, FORE=>2, AFT=>2, EXP=>0);
            NEW_LINE;
            PUT("In PROC_3: X_VALUE = ");
            PUT(X_VALUE, FORE=>2, AFT=>2, EXP=>0);
            NEW_LINE;
        end PROC_3;
    --------------------------------------------

    begin
        PUT("In PROC_2: A_VALUE = ");
        PUT(A_VALUE, FORE=>2, AFT=>2, EXP=>0);
        NEW_LINE;
        PUT("In PROC_2: B_VALUE = ");
        PUT(B_VALUE);
        NEW_LINE;
        PUT("In PROC_2: X_VALUE = ");
        PUT(X_VALUE);
        NEW_LINE;
        PROC_3(99.99);
    end PROC_2;

----------------------------------------------------
-- PROCEDURE 4
    procedure PROC_4 (I_VALUE: INTEGER) is
        Q_VALUE: FLOAT := 88.88;
    begin
        PUT("In PROC_4: A_VALUE = ");
        PUT(A_VALUE);
        NEW_LINE;
        PUT("In PROC_4: B_VALUE = ");
        PUT(B_VALUE);
        NEW_LINE;
        PUT("In PROC_4: I_VALUE = ");
        PUT(I_VALUE);
        NEW_LINE;
        PUT("In PROC_4: Q_VALUE = ");
        PUT(Q_VALUE, FORE=>2, AFT=>2, EXP=>0);
        NEW_LINE;
        PROC_2(4);
     end PROC_4;

----------------------------------------------------
-- TOP LEVEL PROCEDURE
begin
    PUT("In PROC_1: A_VALUE = ");
    PUT(A_VALUE);
    NEW_LINE;
    PUT("In PROC_1: B_VALUE = ");
    PUT(B_VALUE);
    NEW_LINE;
    PROC_2(3);
    PROC_4(4);
end PROC_1;

The associated nesting is given to the right and the expected output below:

In PROC_1: A_VALUE =           1
In PROC_1: B_VALUE =           2
In PROC_2: A_VALUE = 22.22
In PROC_2: B_VALUE =           2
In PROC_2: X_VALUE =           3
In PROC_3: A_VALUE = 22.22
In PROC_3: B_VALUE =           2
In PROC_3: C_VALUE = 99.99
In PROC_3: X_VALUE = 22.22
In PROC_4: A_VALUE =           1
In PROC_4: B_VALUE =           2
In PROC_4: I_VALUE =           4
In PROC_4: Q_VALUE = 88.88
In PROC_2: A_VALUE = 22.22
In PROC_2: B_VALUE =           2
In PROC_2: X_VALUE =           4
In PROC_3: A_VALUE = 22.22
In PROC_3: B_VALUE =           2
In PROC_3: C_VALUE = 99.99
In PROC_3: X_VALUE = 22.22

Some explanation is given in the following Sub-sections.


3.1. PROC_1 SCOPE


3.2. PROC_2 SCOPE


3.3. PROC_3 SCOPE


3.4. PROC_4 SCOPE




Created and maintained by Frans Coenen. Last updated 11 October 1999