Storage Class Specifiers
You should know that before using any variable we have to explicitly or implicitly mention its data type. There is no need to declare constants. Generally a variable can store either in memory or one of the CPU registers. And it is storage class that determines where to store the subsequent variable. The storage class also specifies the scope of the variable. The portion of a program where a variable can be accessed is called as the scope of that variable. The scope of the variable is determined by its place of declaration. If we declare a variable inside a function then this variable can be accessed inside the same function only; such variables are called as local variables. If we declare a variable outside all the functions then this variable can be accessed from anywhere in the program; such variables are called as global variables.
C provides four storage classes:
1. auto Storage Class
2. register Storage Class
3. static Storage Class
4. external Storage Class
The auto Storage Class
The keyword ‘auto’ is used to refer automatic variables. Automatic variable is declared as:
auto data_type variable_name;
If you want to declare i as automatic integer variables, j as automatic float variables and k as automatic character variables then the declaration section looks like this:
auto int i;
auto float j;
auto char k;
automatic variables are stored in memory. The default initial value of a automatic variable is a garbage value. The automatic variables are local to a function in which these variables are defined. It means that automatic variables are created when the function (that defines the auto variables) is called and destroyed when that function terminates. We can also declare an automatic variable at the beginning of a block. It means that each invocation of the statement block in which the auto variable is defined gets a first copy with its own memory space and with reinitialization.
Program – str.cpp illustrates this concept.
// Program – str.cpp
#include
void main()
{
auto int i;
cout << “\nEnter first number =”;
cin >> i;
{
auto int i;
cout << “Enter second number =”;
cin >> i;
{
auto int i;
cout << “Enter third number =”;
cin >> i;
cout << “\nThird I = ” << i;
}
cout << “\nSecond I = ” << i;
}
cout << “\nFirst I = ” << i;
}
The output of this program str is as:
Enter first number = 11
Enter second number = 12
Enter third number = 13
Third = 13
Second = 12
First = 11
In this program the value of I is different for each block because they are defined in different blocks. The life of automatic variable exists till the control remains within block. The value of the variable is lost when the control comes out of the block in which the variable is defined.
You will be surprised to know that if you omit keyword ‘auto’ in the above program, the output will remain same. It means that if storage class of a variable is not mentioned then it is supposed to be auto by default unless the program declares them otherwise. By default the function parameters are auto unless you declare them to be in the register storage class.
The register Storage Class
Register variables are stored inside CPU registers in order to provide fast access. Normally any variable is stored in memory. When a reference is made to access it, it is accessed from memory and then it is stored into CPU register. The keyword ‘register’ is used to refer register variables.
Register variable is declared as:
register data_type variable_name;
Like automatic variables, the default initial value of register variable is garbage value. And like auto variables, the register variables are local to a function. The only difference between an auto variable and a register variable is that you can not take the address of register variable because hardware registers on most computers do not have memory addresses. On the other hand you can take the address of an auto variable.
// Program – str1.cpp
#include
void main()
{
register int i;
cout << “\n Enter any integer value = ”;
cin >> i;
cout << “You have entered = ” << i;
}
The output of this program str1.cpp is as:
Enter any integer value = 10
You have entered =10
While using register storage class, one should remember that if the available registers are not enough, due to any reason, the variables are treated as automatic variables. In other words we can say that when we declare a variable as a register variable then it is a request to the compiler. The compiler can ignore this request. The address restriction applies even when the compiler ignores the request and puts the variable in addressable memory. Another main point to note is that register storage class is restricted to integer variables only because CPU registers are 16 – bit registers & each integer occupies 2 bytes.
Thus the following statement
register float j;
register float k;
would not result in any compiler error. The reason is simple that these variables, j and k, are treated as automatic variables.
The external Storage Class
External variables are also referred as global variables. External variables are declared outside all functions.
An external variable is declared as:
extern data_type variable_name;
Like automatic variables, the external variables are also stored in memory. But unlike automatic variables, the default value of external variable is zero. While using external variables, remember that external variables are not restricted to any function locally. Instead the value of global variable is available to each and every function of the program. Therefore the life of external variable remains present throughout the program and is destroyed only when the program terminates.
Watch carefully the output of the following program:
// Program – str2.cpp
#include
void first();
void second();
int x;
void main()
{
extern int x;
x=15;
cout << "\nFirst X =" << x;
first();
cout << "\nSecond X = " << x;
second();
cout << "\nThird X = " << x;
}
void first()
{
x += 5;
}
void second()
{
x -= 10;
}
The output of this program is as….
X = 15
X = 20
X = 10
An external variable declaration may be inside or outside the function that references it. If the variable is declared outside all functions then every function in the program can reference this external variable. On the other hand if the variable is declared inside a function then only those functions which have the extern declaration of the variable can reference the variable.
Here one main point to note that use of an external outside all the function is optional. That’s why even following program would work correctly.
// Program – str3.cpp
#include
void first();
float y;
void main()
{
y = 20.45;
cout << “\nFirst Y = ” << y;
first();
}
void first()
{
y = y+10.25;
cout << “\nSecond Y = ” << y;
}
The output of this program is as:
Local Y = 27.5
Global Y = 20.25
Thus if there is any conflict between the global and local variable, the local variable wins the race.
The static Storage Class
There are two types of static variables:
1. Static local variables (internal static variable)
2. Static global variables (external static variable)
Static local variables are declared inside a function by using a keyword ‘static’ as:
static datatype variable_name;
A static local variable is initialized only once when the very first call to the function (that defines it) occurs. The value of static local variable would not be destroyed even the function terminates. But remember that the static local variable can be accessed within its own function.
Following program illustrates this concept:
// Program – str4.cpp
#include
void example();
void main()
{
example();
example();
example();
}
void example()
{
static float x = 20.25;
float y = 10.45;
cout << “\n X = “ << x << “\tY = ” << y;
x = x+0.25;
y = y+0.25;
}
The output of this program is as:
X = 20.25 Y = 10.45
X = 20.5 Y = 10.45
X = 20.75 Y = 10.45
In function example(), x is declared as static variable whereas y is declared as automatic variable. Therefore when function example() is called first time, x is initialized to 20.25 once whereas y is initialized each time we call function example().
Like external variable, a static global variable is declared outside any function. But it is slightly different than ordinary external variable. And any file (program) can access ordinary external variable, whereas a static global variable can be only accessed in the file (program) it is defined.
Now let us summarize the different storage classes:
Storage class |
Keyword |
Storage |
Default initial value |
Scope |
Life |
Automatic Storage class |
auto |
memory |
Garbage value |
Local to the block |
temporary |
Register Storage class |
register |
CPU register |
Garbage value |
Local to the block |
temporary |
External Storage class |
extern |
memory |
Zero |
Global to all files |
persistent |
Internal static Storage class |
static |
memory |
Zero |
Local to the block |
persistent |
External Static Storage class |
static |
memory |
Zero |
Global to one file |
persistent |