C54. C Storage Classes


Storage Classes
Storage classes can be specified for variables and to a lesser extent functions and parameters. We'll concentrate on variables for now.
Properties of Variables
Every variable in a C program has three properties:
Storage duration. The storage duration of a variable determines when mem­ory is set aside for the variable and when that memory is released. Storage for a variable with automatic storage duration is allocated when the surrounding  block is executed: storage is deallocated when the block terminates, causing the variable to lose its value. A variable with static storage duration stays at the same storage location as long as the program is running, allowing it to retain its value indefinitely.
Scope. The scope of a variable is the portion of the program text in which the variable can be referenced. A variable can have either block scope (the vari­able is visible from its point of declaration to the end of the enclosing block) or fde scope (the variable is visible from its point of declaration to the end of the enclosing file).
Linkage. The linkage of a variable determines the extent to which it can be shared by different parts of a program. A variable with external linkage may be shared by several (perhaps all) files in a program. A variable with internal linkage is restricted to a single file, but may be shared by the functions in that file. (If a variable with the same name appears in another file, it's treated as a different variable.) A variable with no linkage belongs to a single function and can't be shared at all.
The default storage duration, scope, and linkage of a variable depend on where it's declared:
Variables declared inside a block (including a function body) have automatic storage duration, block scope, and no linkage.

Variables declared outside any block, at the outermost level of a program, have static storage duration, file scope, and external linkage.

The auto Storage Class
The auto storage class is legal only for variables that belong to a block. An auto variable has automatic storage duration (not surprisingly), block scope, and no linkage. The auto storage class is almost never specified explicitly, since it's the default for variables declared inside a block..

The static Storage Class
The static storage class can be used with all variables, regardless of where they're declared, but it has a different effect on a variable declared outside a block than it does on a variable declared inside a block. When used outside a block, the word static specifies that a variable has internal linkage. When used inside a block, static changes the variable's storage duration from automatic to static.
A static variable declared within a block resides at the same storage loca­tion throughout program execution. Unlike automatic variables, which lose their values each time the program leaves the enclosing block, a static variable will retain its value indefinitely, static variables have some interesting properties:
A static variable in a block is initialized only once, prior to program execu­tion. An auto variable is initialized every time it comes into existence (pro­vided. of course, that it has an initializer).
Each time a function is called recursively, it gets a new set of auto variables. If it has a static variable, on the other hand, that variable is shared by all calls of the function.

Although a function shouldn't return a pointer to an auto variable, there's nothing wrong with it returning a pointer to a static variable.

The extern Storage Class
The extern storage class enables several source files to share the same variable.  
extern int i;
informs the compiler that i is an int variable, but doesn't cause it to allocate memory for i. In C terminology, this declaration is not a definition of i; it merely informs the compiler that we need access to a variable that's defined elsewhere (perhaps later in the same file, or more often in another file). A variable can have many declarations in a program but should have only one definition.
There's one exception to the nile that an extern declaration of a variable isn't a definition. An extern declaration that initializes a variable serves as a def­inition of the variable.
The register Storage Class
Using the register storage class in the declaration of a variable asks the com­piler to store the variable in a register instead of keeping it in main memory like other variables. (A register is a storage area located in a computer's CPU. Data stored in a register can be accessed and updated faster than data stored in ordinary memory.) Specifying the storage class of a variable to be register is a request, not a command. The compiler is free to store a register variable in memory if it chooses.
The register storage class is legal only for variables declared in a block. A register variable has the same storage duration, scope, and linkage as an auto variable. However, a register variable lacks one property that an auto vari­able has: since registers don't have addresses, it's illegal to use the & operator to take the address of a register variable. This restriction applies even if the com­piler has elected to store the variable in memory.
register is best used for variables that are accessed and/or updated frequently.

register isn't nearly as popular among C programmers as it once was. Today's compilers are much more sophisticated than early C compilers; many can determine automatically which variables would benefit the most from being kept in registers. Still, using register provides useful information that can help the compiler optimize the performance of a program. In particular, the compiler knows that a register variable can't have its address taken, and therefore can't be modified through a pointer. In this respect, the register keyword is related to C99's restrict keyword.




The Storage Class of a Function
Function declarations (and definitions), like variable declarations, may include a storage class, but the only options are extern and static. The word extern at the beginning of a function declaration specifies that the function has external linkage, allowing it to be called from other files, static indicates internal link­age, limiting use of the function's name to the file in which it's defined. If no stor­age class is specified, the function is assumed to have external linkage. Consider the following function declarations:
extern int f(int i) ;
static int g(int i) ;
int h(int i) ;
f has external linkage, g has internal linkage, and h (by default) has external link­age. Because it has internal linkage, g can't be called directly from outside the file in which it's defined. (Declaring g to be static doesn't completely prevent it from being called in another file; an indirect call via a function pointer is still pos­sible.)

Declaring functions to be extern is like declaring variables to be auto—it serves no purpose. For that reason. 1 don't use extern in function declarations. Be aware, however, that some programmers use extern extensively, which cer­tainly does no harm.
Declaring functions to be static, on the other hand, is quite useful. In fact. 1 recommend using static when declaring any function that isn't intended to be called from other files. The benefits of doing so include:
Easier maintenance. Declaring a function f to be static guarantees that f isn't visible outside the file in which its definition appears. As a result, some­one modifying the program later knows that changes to f won't affect func­tions in other files. (One exception: a function in another file that's passed a pointer to f might be affected by changes to f. Fortunately, that situation is easy to spot by examining the file in which f is defined, since the function that passes f must also be defined there.)
Reduced "name space pollution." Since functions declared static have internal linkage, their names can be reused in other files. Although we proba bly wouldn't deliberately reuse a function name for some other purpose, it can be hard to avoid in large programs. An excessive number of names with exter­nal linkage can result in what C programmers call "name space pollution": names in different files accidentally conflicting with each other. Using static helps prevent this problem.
Function parameters have the same properties as auto variables: automatic storage duration, block scope, and no linkage. The only storage class that can be specified for parameters is register.

No comments: