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 memory 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 variable 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 location 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
execution. An auto variable is initialized every time it comes into existence
(provided. 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 definition of the variable.
The register Storage Class
Using the register storage class in the declaration of a variable asks the compiler 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 variable 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 compiler 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 linkage, limiting use of the function's name to the file in which
it's defined. If no storage 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 linkage. 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 possible.)
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 certainly
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, someone modifying the
program later knows that changes to f won't affect functions 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 external 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:
Post a Comment