Home | Projects | Notes > C Programming > Storage Classes
Storage classes can be specified for variables and - to a lesser extent - functions and parameters. We'll concentrate on variables for now.
The term block refers to the body of a function (the part enclosed in braces) or a compound statement, possibly containing declarations.
Every variable in a C/C++ program has three properties:
Storage duration
Scope
Linkage
Determines when memory is set aside for the variable and when that memory is released.
Automatic storage duration
Allocated when the surrounding block is executed
Deallocated when the block terminates, causing the variable to lose its value.
Static storage duration
Stays at the same storage location as long as the program is running, allowing it to retain its value indefinitely.
The portion of the program text in which the variable can be referenced.
Block scope
The variable is visible from its point of declaration to the end of the closing block.
File scope
The variable is visible from its point of declaration to the end of the enclosing file.
Determines the extent to which it can be shared by different parts of a program.
External linkage
May be shared by several (perhaps all) files (compilation units or source modules) in a program.
Internal linkage
Restricted to a single file, but may be shared by the functions in that file.
No linkage
Belongs to a single function and can't be shared at all.
By default storage duration, scope, and linkage of a variable depend on where it is declared.
Variables declared inside a block (including a function body)
automatic storage duration
block scope
no linkage
Variables declared outside any block, at the outermost level of a program
static storage duration
file scope
external linkage
Example
xxxxxxxxxx
61int i; // static storage, file scope, external linkage
2
3void f(void)
4{
5 int j; // automatic storage duration, block scope, no linkage
6}
For many variables, the default storage duration, scope, and linkage are satisfactory. When they aren't, we can alter these properties by specifying an explicit storage class: auto
, static
, extern
, or register
.
auto
Storage ClassLegal only for variables that belong to a block.
An auto
variable has:
automatic storage duration
block scope
no linkage
Default for variables declared inside a block (so almost never specified explicitly)
static
Storage ClassCan be used with all variables, regardless of where they are declared
The effect on a variable differs depending on where it is used:
Outside a block - static
specifies that a variable has internal linkage
Inside a block - static
changes the variable's storage duration from automatic to static
xxxxxxxxxx
61static int i; // static storage, file scope, internal linkage
2
3void f(void)
4{
5 static int j; // static storage, block scope, no linkage
6}
When used in declaration outside a block, static
essentially hides a variable within the file in which it's declared; only functions that appear in the same file can see the variable.
In the following example, the functions f1
and f2
both have access to i
, but functions in other files don't:
xxxxxxxxxx
41static int i;
2
3void f1(void) { /* has access to i */ }
4void f2(void) { /* has access to i */ }
extern
Storage ClassEnables several source files to share the same variable
xxxxxxxxxx
11extern int i;
Informs the compiler that
i
is anint
variable, but doesn't cause it to allocate memory fori
Informs the compiler that we need access to a variable that's defined elsewhere
A variable in an extern
declaration has:
static storage duration
scope dependent on the declaration's placement:
xxxxxxxxxx
61extern int i; // static storage duration, file scope, ? linkage
2
3void f(void)
4{
5 external int j; // static storage duration, block scope, ? linkage
6}
Determining the linkage of an
extern
variable is a bit harder.
If the variable was declared
static
in the file (outside of any function definition), then it has internal linkage.Otherwise (the normal case), the variable has external linkage.
register
Storage ClassAsks the compiler to store the variable in a register instead of keeping it in main memory like other variables.
This is a request to the compiler, not a command. It is the compiler's choice whether the variable will be stored in a register or in memory.
Only legal for variables declared in a block
A register
variable has the same storage duration, scope and linkage as an auto
variable.
One restriction is that 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. (Why? Because it saves memory access time?)
e.g., The loop control variable in a for
statement is a good candidate for register
treatment:
xxxxxxxxxx
101int sum_array(int a[], int n)
2{
3 register int i;
4 int sum = 0;
5
6 for (i = 0; i < n; i++)
7 sum += a[i];
8
9 return sum;
10}
Only options are extern
and static
extern
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.
Examples:
xxxxxxxxxx
31extern int f(int i); // f has external linkage
2static int g(int i); // g has internal linkage
3int h(int i); // h (by default) has external linkage
Because of its internal linkage,
g
can't be called directly from outside the file in which it's defined. (Declaringg
to bestatic
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 static
has some benefits:
Easier maintenance
Reduced "name space pollution"
Function parameters have the same properties as auto
variables:
automatic storage duration
block scope
no linkage
The following program fragment shows all possible ways to include - or omit - storage classes in declarations of variables and parameters.
xxxxxxxxxx
121int a;
2extern int b;
3static int c;
4
5void f(int d, register int e)
6{
7 auto int g;
8 int h;
9 static int i;
10 extern int j;
11 register int k;
12}
xxxxxxxxxx
131Name Storage Duration Scope Linkage
2==== ================== ====== ========
3a static file external
4b static file ?
5c static file internal
6d automatic block none
7e automatic block none
8g automatic block none
9h automatic block none
10i static block none
11j static block ?
12k automatic block none
13---- ------------------ ------ --------
?: The definitions of
b
andj
aren't shown, so it's not possible to determine the linkage of these variables. In most cases, the variables will be defined in another file and will have external linkage.