


                                                        Chapter 9
                                    BLOCKS AND SCOPE OF VARIABLES


LARGE PROJECT DECOMPOSITION
_________________________________________________________________

Since Ada is a highly structured language, it has the means to
divide a large project into many smaller projects through use of
procedures and functions.  Because procedures and functions can be
nested within other procedures and functions, we have the problem
of visibility and scope of types, variables, constants, and
subprograms.


WHAT IS THE SCOPE OF A VARIABLE?
_________________________________________________________________

Examine the program named SCOPE.ADA for several   ===============
examples of variables with different scopes.         SCOPE.ADA
You should spend a few minutes familiarizing      ===============
yourself with the structure of the program which
contains the main program, or procedure, and
four procedures embedded within it.  We will begin with the
variable named Count declared in line 4, and state that it has a
scope which extends from the semicolon at the end of its
declaration to the end of the entire program in line 32.  Its scope
extends to the end of the program because it is declared in the
declaration part of the main program.  It is commonly referred to
as a global variable.



WHERE IS A VARIABLE VISIBLE?
_________________________________________________________________

The variable named Count, declared in line 4, is visible anyplace
in the range of its scope, except for one small area of the
program.  Since another variable with the same name is defined in
line 10, the first one is effectively hidden from view within the
range of the newer, local variable.  Note that it is the local
variable that takes precedence and hides the global variable,
rather than the other way.  The variable named Count from line 4,
is not visible from the end of line 10 through the end of line 13.
It should be clear that the scope of the local variable extends to
the end of the executable portion of the subprogram in which it is
declared.

In like manner, the variable named Index, defined in line 7, has
a scope that extends from the end of line 7 to the end of its
procedure which ends in line 23.  The variable named Index is
visible throughout its range, because there are no other variables
of the same name in a lower level subprogram.  The variable named

                                                         Page 9-1

                        Chapter 9 - Blocks and Scope of Variables

Data is visible throughout its range which extends from the end of
line 16 through 19.


THAT WAS ACTUALLY A LIE
_________________________________________________________________

The global variable Count is not visible from lines 10 through 13,
but there is a way to use it in spite of its hidden nature.  This
will be the topic of the next example program, but you should
compile and run the present program to see that it really will
compile as given.  There is no output, so execution will be
uninteresting.


USING THE DOT NOTATION
_________________________________________________________________

Examine the program named SCOPE2.ADA for some    ================
examples of making an invisible variable            SCOPE2.ADA
visible.  The careful observer will notice that  ================
this is the structure of the last program with
additional variables declared, and some added
assignment statements.

We will consider three variables of the same name, Count, and see
that we can use all three variables in a single statement if we so
desire.  Assume we are at line 12 in the program where we wish to
use the local variable named Count, the one that was declared in
line 10.  By the definition of Ada, the innermost variable will
take precedence and by simply using the name Count, we are using
the desired one.  If however, we would like to use the one declared
in line 4, we can do so by using the "dot" notation illustrated in
line 13.  We are giving the compiler a complete map on where to
find the variable.  The dot notation can be read as follows, "Go
to the outer level, Scope2, dot, and the variable named Count."
Line 13 is therefore referring to the variable declared in line 4.
Using the notation Scope2.Level1.Count would refer to the variable
declared in line 7.

Additional examples of the use of dot notation to use otherwise
invisible variables are given in lines 21 through 30.  This is also
called the expanded name of the variable or the expanded naming
convention.


RENAMING A VARIABLE
_________________________________________________________________

In order to reduce the number of keystrokes used and to improve the
clarity of some programs, Ada provides a renaming capability.  Line
18 illustrates this by renaming the triple component combination
to the much simpler name, Outer_Index.  Anyplace in the program
where it is permissible to use the longer name, it is also legal

                                                         Page 9-2

                        Chapter 9 - Blocks and Scope of Variables

to use the new shorter name, because they are simply synonyms for
the same actual variable.  This is a construct that could easily
be abused in a program and make a program unnecessarily
complicated, so it should be used sparingly.

Compile and run this program, even though it has no output, to
assure yourself that it actually will compile.  The dot notation
will be used in many other places in Ada, so you should become
familiar with it.



AN ADA BLOCK
_________________________________________________________________

Examine the program named BLOCKS.ADA for an      ================
example of the use of an Ada block.  Just as you    BLOCKS.ADA
can define a procedure and jump to it, by        ================
calling it of course, Ada allows you to define
the equivalent of a procedure and execute it as
inline code.  Such a section of code is called a block and has the
form of three reserved words, declare, begin, and end, with
declarations between the declare and begin, and executable
statements between the begin and end.  Any new types, subtypes,
variables, constants, and even subprograms can be declared in the
declaration part of the block and used in the executable part.  The
scope of the declarations begin where they are declared, and end
at the end of the block.



A BLOCK IS A SINGLE STATEMENT
_________________________________________________________________

A block is a single statement and because it is, it can be put
anywhere that it is legal to put any other executable statement.
It could be used within a loop, in one branch of an if statement,
or even as one of the cases of a case statement.  The example
program contains two such blocks, the first in lines 20 through 30,
and the second in lines 37 through 50.  The only real difference
is that the second block is a named block, with the name Who, the
use of which will be defined shortly.

Study the program and you will see that even though there are
several variables defined in the block, and at least one is a
repeat of a global variable, all are actually available through use
of the dot notation defined during our study of the last program.
In the first block, the local variables are the default variables
when there is a repeated name, but in the second block, the
variables can be specifically named by using the dot notation.
This is possible because the block is named, the name being Who in
this particular case.  The name is mentioned just prior to the
block followed by a colon, and the name is repeated following the
end of the block.  In this case, the name does nothing for you, but

                                                         Page 9-3

                        Chapter 9 - Blocks and Scope of Variables

if there were two nested blocks, either or both could be named, and
you would be able to select which variable you were interested in.
There is no limit to the number of blocks that can be nested.

Note that the name used for a block is not a label to which you can
jump to in order to execute a goto statement.  The name is only to
name the block.

If no declarations are needed, you can declare a block without the
reserved word declare, using only the execution block delimiters
begin and end.  Without the declaration part, there is little
reason to declare the block until we come to the topic of exception
handling where it will be extremely useful to have this capability.
Compile and execute this program and study the results.  Be sure
you understand where each of the displayed values come from.


WHAT ARE AUTOMATIC VARIABLES?
_________________________________________________________________

This is a good time to discuss a very important  ================
topic that can have a significant effect on how    AUTOMATC.ADA
you write some of your programs in the future.   ================
The topic is automatic variables, what they are
and what they do for you.  The best way to
define them is to examine another program, and the program named
AUTOMATC.ADA is written just to illustrate this point.

The program is actually very simple since it is merely one big loop
in which the variable Index covers the range from 1 through 10.
Each time through the loop, the block in lines 19 through 29 is
executed and contains another loop to output some integer type
data.  Take careful notice of the constants and the way they are
used, and you will see something that is a little strange.  Each
time we enter the block, we enter with a larger value for the loop
variable, in this case named Index, and therefore the constants are
different each time through the block.  During each pass, however,
they are constant, and will be treated as such.  This behavior is
perfectly normal and will be clearly understood when we define an
automatic variable.

Prior to entering the block, the two constants, and the variable
named Count_Stuff do not exist.  When the block is entered, the
constants are generated by the system, initialized to their
constant values, and available for use within the block.  Since the
constants are generated each time the block is entered, it is
possible to assign them a different value each time, which is
exactly what is being done here.  The process of assigning the
constants their values is called elaboration.

The variable is also generated, and made available for use within
the block where it is assigned a nonsense value for illustrative
purposes, then never used.  When program control leaves the block,
in this case dropping out the bottom, the two constants and the

                                                         Page 9-4

                        Chapter 9 - Blocks and Scope of Variables

variable disappear from existence entirely and are no longer
available for use anywhere in the program.  They are said to have
a limited lifetime, their lifetime being from the time they are
elaborated until we leave the block in which they are declared.
The scope and lifetime of a variable or constant is therefore very
important for you to understand.

It should be clear to you that the outer loop variable, Index, is
visible from lines 15 through 32 except for lines 26 through 28.
Within the region of lines 26 through 28, the outer loop variable
cannot be used, even by using the expanded naming convention (i.e.
- the dot notation), because there is no name for the outer loop.
Naming the outer loop would make the outer loop variable available.



WHERE ELSE IS THIS USED?
_________________________________________________________________

This concept of the automatic variable is very important because
it is used in so many places throughout an Ada program.  It is used
in four different places in the present example program, once in
the block, as we have just mentioned, once in the main program
itself, where the four variables with animal names are
automatically generated, and twice in the for loops.  The variables
named Index in each of the for loops are actually automatic
variables that are generated when the loop is entered, and
discarded when the loop is completed.  As you can see, there is a
very good reason why the loop control variable is not available
after you leave the loop.

Each time you call a procedure or function, the formal parameters
are generated, as are the defined variables and constants.  The
process of variable generation and constant initialization is
called elaboration.  They are then used within the subprograms, and
discarded when the procedure or function is completed and control
is returned to the calling program.

Since the main program is itself a procedure, its variables are
handled the same way.



THE STACK STORES THE AUTOMATIC ENTITIES
_________________________________________________________________

The generated constants and variables are stored on an internal
stack, the definition of which is beyond the scope of this
tutorial.  If you understand what a stack is, it should be clear
to you how the system can generate items, place them on the stack,
use them, and discard them.  Also, due to the nature of a stack,
it should be clear to you how additional variables can be placed
on the stack as calls are made to more deeply nested procedures and
functions.  Finally, it is only because of this use of automatic

                                                         Page 9-5

                        Chapter 9 - Blocks and Scope of Variables

variables that recursive subprograms can be used.  Ada requires
that all subprograms be re-entrant and use of the stack also makes
this possible.

If the last paragraph is too technical for you, don't worry about
it, because it is only mentioned for general information, and is
not needed to understand Ada programming.

Compile and run AUTOMATC.ADA and study the output.  Be sure you
understand the concept of the automatic variable because some of
the advanced programming techniques in Ada will require this
knowledge.



PROGRAMMING EXERCISES
_________________________________________________________________

1.   Modify BLOCKS.ADA to include a procedure in the declaration
     part of the first block.  The procedure should output a line
     of text to the monitor when called from the executable part
     of the block.  Why can't this procedure be called from outside
     of the block?

2.   Name the block in AUTOMATC.ADA and output the value of the
     outer Index in the loop using the dot notation.  It will
     output the same number six times since the outer Index is
     invariant in the inner loop.

























                                                         Page 9-6