Scope rules govern the lifetime and visibility of data items (i.e. the parts of a program where they can be used).
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;
Consider the following example program (Nesting illustrated in diagram to right):
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).
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).
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.
In this case the declared items have nothing to do with one another (other than sharing the same name). For example:
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).
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:
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.
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):
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.
Consider the following Ada program
-- 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.
Created and maintained by Frans Coenen. Last updated 11 October 1999