![]() |
Essentials of C++: Section IV |
|
A. Scope
Identifiers in a program are only known (or useable) in parts of the program. Where in a program an identifier is usable is referred to as the scope of the identifier. Some identifiers have global scope, meaning they are usable everywhere in a file or in all files of the program. Most identifiers have a more local scope meaning they are usable in some subset of the program's code. The most common local scope is block scope. (C++ treats all the
statements inside a set of matching braces as a block of code.). Such
variables are usable from their declaration point in some block of code
(inside a pair of braces) until the end of the block. Function parameters
are also considered to have block scope - the block defining the
function's code - even though they are technically declared before the
beginning brace of the function block. Global scope is also known as file scope. Identifiers with this scope are declared in a file but outside all blocks and classes. They are known from the point of declaration to the end of the file. To be accessible in other files, such identifiers must be re-declared in the other files using the word 'extern' as in:
This tells the compiler to not allocate more memory for this identifier
but to wait until link time to find the original declaration/definition.
A third scope is class scope. See the discussion of classes and
encapsulation for more on this. Since most identifiers have block scope, it is legal and common to have
the same identifier name used for different purposes in different blocks
of a program. While the rules for when identifiers must be unique are more
complex than just described (Check under 'name spaces' in your manual for
the full details), a simple rule of thumb is that all identifers in the
same scope should be unique. Following this rule should avoid any
syntactic errors and will also make your code easier to
understand. B. Duration Variable and constant identifiers are, however, limited in terms of the
period in a program's execution when the identifiers are associated with
specific memory locations - an issue referred to as the duration of
the variable or constant. There are three types of duration:
static, local, and dynamic. Static identifiers are
allocated memory from the moment execution begins and the allocation lasts
until the program terminates. All functions have static duration -
otherwise, they might not be available when needed. All variables and
constants with file scope also have static duration. This allows their
memory to be accessed whenever they are usable according to the scope
rules. Static identifiers are initialized to zero when there is no
specific initialization in the code. Identifiers with local (or automatic) duration have memory allocated to
them only when the system is performing the block of code in which the
identifier is declared. Thus, they go in and out of existence as the
program moves through the code. In addition, when memory is allocated for
such identifiers, the contents of that memory is unpredictable unless
there is a specific initialization. Thus, there is the danger that the
memory associated with a local duration identifier contains garbage. There is a close relationship between local duration and block scope.
In fact, block scope is also referred to as local scope. All identifiers
with local duration also have local scope - it would make no sense to have
an identifier that was usable but did not have memory allocated to it. On
the other hand, it is possible for a static duration object to have local
scope. In other words, the memory is always allocated but that memory is
only accessible in parts of the program. The third type of duration, dynamic, refers to identifiers whose memory
allocation takes place at run time through specific requests for memory.
It is up to the programmer to decide when the allocation will take place
and how much memory will be allocated. Another way to view this is in
terms of compile-time vs. run-time memory allocation. At
compile time, no memory is allocated for any identifiers. However, the
compiler writes the instructions to declare memory for static and local
duration identifiers so it is technically possible to know how much memory
will be required for identifiers of these types. Since identifiers with
dynamic duration are only allocated memory if the code making the request
is reached and the amount of memory allocated depends on the way the code
is written, it is impossible to tell until the code has finished running
how much memory will be (was) required. Such memory allocation is referred
to as run-time allocation as opposed to compile-time
allocation. Links to 'The Story of C++" and other documents
|