6.9. Storage Classes
The programs you have seen so far use identifiers for variable names. The attributes of variables include name, type, size and value. This chapter also uses identifiers as names for user-defined functions. Actually, each identifier in a program has other attributes, including storage class, scope and linkage.
C++ provides five storage-class specifiers: auto, register, extern, mutable and static. This section discusses storage-class specifiers auto, register, extern and static. Storage-class specifier mutable (discussed in detail in Chapter 24) is used exclusively with classes.
Storage Class, Scope and Linkage
An identifier's storage class determines the period during which that identifier exists in memory. Some identifiers exist briefly, some are repeatedly created and destroyed and others exist for the entire execution of a program. This section discusses two storage classes: static and automatic.
An identifier's scope is where the identifier can be referenced in a program. Some identifiers can be referenced throughout a program; others can be referenced from only limited portions of a program. Section 6.10 discusses the scope of identifiers.
An identifier's linkage determines whether an identifier is known only in the source file where it is declared or across multiple files that are compiled, then linked together. An identifier's storage-class specifier helps determine its storage class and linkage.
Storage Class Categories
The storage-class specifiers can be split into two storage classes: automatic storage class and static storage class. Keywords auto and register are used to declare variables of the automatic storage class. Such variables are created when program execution enters the block in which they are defined, they exist while the block is active and they are destroyed when the program exits the block.
Only local variables of a function can be of automatic storage class. A function's local variables and parameters normally are of automatic storage class. The storage class specifier auto explicitly declares variables of automatic storage class. For example, the following declaration indicates that double variables x and y are local variables of automatic storage classthey exist only in the nearest enclosing pair of curly braces within the body of the function in which the definition appears:
auto double x, y;
Local variables are of automatic storage class by default, so keyword auto rarely is used. For the remainder of the text, we refer to variables of automatic storage class simply as automatic variables.
Performance Tip 6.1
Software Engineering Observation 6.8
Data in the machine-language version of a program is normally loaded into registers for calculations and other processing.
Performance Tip 6.2
Common Programming Error 6.11
The compiler might ignore register declarations. For example, there might not be a sufficient number of registers available for the compiler to use. The following definition suggests that the integer variable counter be placed in one of the computer's registers; regardless of whether the compiler does this, counter is initialized to 1:
register int counter = 1;
The register keyword can be used only with local variables and function parameters.
Performance Tip 6.3
Static Storage Class
Keywords extern and static declare identifiers for variables of the static storage class and for functions. Static-storage-class variables exist from the point at which the program begins execution and last for the duration of the program. A static-storage-class variable's storage is allocated when the program begins execution. Such a variable is initialized once when its declaration is encountered. For functions, the name of the function exists when the program begins execution, just as for all other functions. However, even though the variables and the function names exist from the start of program execution, this does not mean that these identifiers can be used throughout the program. Storage class and scope (where a name can be used) are separate issues, as we will see in Section 6.10.
Identifiers with Static Storage Class
There are two types of identifiers with static storage classexternal identifiers (such as global variables and global function names) and local variables declared with the storage class specifier static. Global variables are created by placing variable declarations outside any class or function definition. Global variables retain their values throughout the execution of the program. Global variables and global functions can be referenced by any function that follows their declarations or definitions in the source file.
Software Engineering Observation 6.9
Software Engineering Observation 6.10
Local variables declared with the keyword static are still known only in the function in which they are declared, but, unlike automatic variables, static local variables retain their values when the function returns to its caller. The next time the function is called, the static local variables contain the values they had when the function last completed execution. The following statement declares local variable count to be static and to be initialized to 1:
static int count = 1;
All numeric variables of the static storage class are initialized to zero if they are not explicitly initialized by the programmer, but it is nevertheless a good practice to explicitly initialize all variables.
Storage-class specifiers extern and static have special meaning when they are applied explicitly to external identifiers such as global variables and global function names. In Appendix E, C Legacy Code Topics, we discuss using extern and static with external identifiers and multiple-source-file programs.