Storage Classes in C

Storage classes in C decide the behavior or properties of a variable like storage, initial values, scope, and lifetime.

Storage area:- Where the variables stored.
Initial values:- The initial (by default) value of a variable without initialization.
Scope:- In which blocks these variables are available that is where we can use these variables.
Lifetime:- Until where these variables are active or live in memory.

C language provides four storage classes specifiers. Those can be used along with the data type specifiers in the declaration statement of a variable. These four storage class specifiers are:-
auto
register
static
extern

The storage class specifiers in C language used before the declaration statement for a variable. We will discuss every storage class specifier with variables one-by-one.

Syntax:-
storage-class-specifier data-type variable-name;

For example:-
auto int number;
static float sum=10;

Local and Global Variables

To understand the storage class in C language, firstly we should know about local and global variables. The variables declared inside a function or block called a local variable. The variables declared outside of a function called a global variable.

#include<stdio.h>
int a = 1; //global variable
void display()
{
   int b = 2; //local variable of display function
   printf("b = %d\n",b);
}
int main()
{
      int c = 3;//local variable of main function
      static int d = 4;//local variable of main function
      printf("a = %d\n",a);
      display();
      printf("c = %d\n",c);
      printf("d = %d\n",d);
      {
        int e = 5;//local variable to this block only
        printf("e = %d\n",e);
      }
      return 0;
}

Output:-

a = 1
b = 2
c = 3
d = 4
e = 5

In the Storage class specifiers, the variable declared will be,
auto:- only local variable
register:- only local variable
static:- Both local and global variable
extern:- only global variable

Storage classes in C: auto

Storage area:- Main memory
Initial value:- Unpredictable value or garbage value
Scope:- Block scope (Local scope)
Lifetime:- Automatic lifetime

The keyword auto is used in the declaration of a variable to explicitly specify its storage class. By default, all variables declared within the body of any function are automatic variables. So, it means the keyword auto is optional, we need not explicitly define them.

#include<stdio.h>
int main()
{
      auto int a=10;
      int b = 20;
      printf("Value of a = %d\n",a);
      printf("Value of b = %d",b);
      return 0;
}

Output:-

Value of a = 10
Value of b = 20

Both variables, a and b declared as auto variables. These are declared inside the main function of the program.

We can declare an auto variable only as local, not as a global variable. If we declare it as a global variable then we will get a compile-time error: file-scope declaration of ‘variableName’ specifies ‘auto’.

#include<stdio.h>
auto int a = 1;
int main()
{
    printf("a = %d\n",a);
    return 0;
}
// error: file-scope declaration of ‘a’ specifies ‘auto’

The default value of auto variables

The auto variables are stored in the primary memory (RAM) of the computer and behave as local variables of the function. When the function in which the variable declares, invoked then automatically these variables created. An auto variable can be initialized when it is defined or left uninitialized. If initialized, it receives the same initialization value each time it is created. If it is not initialized, its value will be undefined every time it is born. So, when the auto variable is not initialized, its value is unpredictable.

#include<stdio.h>
int main()
{
      int a;
      int b;
      printf("Value of a = %d\n",a);
      printf("Value of b = %d\n",b);
      a = 10;
      printf("a = %d\n",a);
      printf("b = %d\n",b);
      return 0;
}

Output:-

Value of a = 59
Value of b = 88
a = 10
b = 88

Initially, the variables a and b are not initialized so the value of both variables is unpredictable or garbage value. Later the variable a is initialized with 10 so, the value of a becomes 10 and the value of b remains garbage.

Why the initial value of auto variables are garbage or unpredictable value?

When the function in which the auto variable declared is invoked then it will be created automatically in the computer RAM area. Here only memory is allocated for the variable. That memory can hold the value/data of any previous program. If we are not initializing the variable then we are getting this value of the previous program (any type of program, not only C). So, it is recommended to initialize all the variables of a program whose default value is garbage. We must initialize these variables before using it in the program otherwise we will get unexpected results.

Scope and lifetime of auto variables

The scope of the auto variable is block scope and lifetime is from where it is declared to the end of the block.

#include<stdio.h>
void display()
{
   //printf("Value of a = %d\n",a);
   //error: ‘a’ undeclared (first use in this function)
   int a = 20;
   printf("Value of a inside function = %d\n",a);
}
int main()
{
      int a=0;
      {
        printf("a = %d\n",a);
        int a = 9;
        printf("a = %d\n",a);
      }
      display();
      printf("a = %d\n",a);
      return 0;
}

Output:-

a = 0
a = 9
Value of a inside function = 20
a = 0

Explanation of this program

Execution starts from the main function and the auto variable ‘a’ is initialized with 0. From the 4th line of the main function, one new block is created. Inside this block value of a is displayed. Later one new auto variable is created which name is the same as the previous variable ‘a’. The value of the new variable is displayed. Now, the block is completed, hence the new variable ‘a’ is unallocated from the memory because the auto variable scope is block scope. The variable created at the 3rd line in the main function with value 0, is the only alive variable After completion of this block. This variable scope is only inside the main function. Inside the display() function, this variable can not be accessed. There is no variable having name ‘a’ in this function so the first line gives an error.

Later, one new auto variable having the name ‘a’ is created. The value of this variable is displayed to the screen. After completion of the display() function, this new variable is also unallocated, the control of the program came back to the main function. Now, the variable created at the third line in the main function is alive and accessible.

Scope of a variable is discussed in more details here:- Scope of variables in C

#include<stdio.h>
void increment()
{
   int i=0;
   i++;
   printf("%d\t",i);
}
int main()
{
   increment();
   increment();
   increment();
   return 0;
}

Output:-

1 1 1

Storage classes in C: register

Storage area:- CPU registers
Initial value:- Unpredictable value or garbage value
Scope:- Block scope (Local scope)
Life time:- Automatic lifetime

The keyword register is used to declare register variables. A register variable is the same as the auto variable, only difference of storage area. Note:- The register storage can be specified only to a local variable, not to global variables.

#include<stdio.h>
//register int a = 1;
//error: register name not specified for ‘a’
int main()
{
   register int b = 9;
   register int c;
   printf("b = %d\n",b);
   printf("c = %d\n",c);
   return 0;
}

Output:-

b = 9
c = -1053106096

Similar to auto variables, the default value of the register variable is unpredictable or garbage value. The scope and lifetime of a register variable are similar to that of automatic variables. When there is repeated use of any variable in the program (like loop statement) in that case, Register storage is ideal for use.

#include<stdio.h>
int main()
{
   register int i;
   for(i=1; i<=10; i++)
   {
     printf("%d\t",i);
   }
   return 0;
}

Purpose of register declaration

Whenever we declare a variable as register then we are telling that this variable is very important for us, and we are going to use it very frequently in the programming language so we want to access it very fastly.

How the computer can help us? There are some types of memory in computer, such as main memory, secondary memory (hard disk), cache or CPU registers. Cache and main memory used generally for store the variable. Secondary memory also can be used but generally whenever we are executing the program then all variables are stored in main memory and cache memory.

We can store variables in CPU registers also. If we store a variable in the CPU register area then we can access the fastest among all memory. CPU registers decrease access time so we can access it in a very fast way. When we use register declaration with a variable then compiler tries to store that variable in CPU registers. CPU registers are very limited in size so it is not compulsory. They are 32-bit, 64-bit depending upon the architecture of the computer.

If we want to keep all the variables in the program within CPU registers, then it may not be possible. Because there are many other important programs (like operating system) are running in the computer, whenever we ask the compiler to store the variables within the CPU register then at that moment CPU register may or may not be available. If the CPU register is not available then the compiler can’t store the variable in CPU registers.

The compiler takes this instruction (register declaration) as advised. If the compiler is not able to store variables in CPU registers then it will store the variables in main memory (means it will be treated like auto variables).

Advantage and disadvantage of the register variables

Advantage:- Register variables may be faster than auto variables.
Disadvantage:- We can’t use the pointer with register variables.

Whenever we declare a variable as register than we should not try to use the address of the variable. Depending upon the situation, the variables might be stored in CPU registers or main memory. So, we shouldn’t use & operator. The address of the registered variable can’t be displayed.

#include<stdio.h>
int main()
{
   register int i;
   printf("%u",&i);
   return 0;
}
// error: address of register variable ‘i’ requested

However, modern compilers are very good at code optimization and there is a rare chance that using register variables our program execution becomes faster. Unless you are working on an embedded system where you know how to optimize the code for the given applications, there is no use of register variables.

Storage classes in C: static

Storage area:- Main memory
Initial value:- Zero
Scope:- Block scope or file scope
Life time:- Static lifetime (until program execution)

The static variables declared with the keyword static. The static variable initial value is 0.

#include<stdio.h>
int main()
{
   static int i;
   printf("The default value of i = %d",i);
   return 0;
}
// default value of i = 0

Static variables are created/initialized only once for the first time, they have been invoked and it is shared by that function several times. Static variables are alive until program execution.

#include<stdio.h>
void increment()
{
   static int i;
   i++;
   printf("%d\t",i);
}
int main()
{
   increment();
   increment();
   increment();
   return 0;
}

Output:-

1 2 3

Storage classes in C: extern

Storage area:- Primary memory
Initial value:- Zero
Scope:- File scope
Lifetime:- Static lifetime (until program execution)

A program in C, particularly when it is large, can be broken up into smaller programs. After compiling these, each program file can be joined together to form the large program. These small programs modules that combine together may need some variable that is used by all of them. In C, such a provision can be made by specifying these variables, accessible to all the small program modules, as an external storage class variable. These variables are global to all the small program modules that are formed as separate files. The keyword for declaring such global variables is extern.
Such a global variable is declared like any other variable in one of the program modules while the declaration of these variables is preceded with the keyword extern in all other combining program modules.

The program modules may also be a function or a block. These variables remain in existence as long as the program is in execution and their existence does not terminate upon the exit of a function or block or a program module from its state of execution. These variables are stored in the primary memory and their default value is zero.

Save below program as variable.c

//variable.c
extern int i; //refer i in program1.c
void show()
{
   int j;
   j=i*2;
   printf("\nValue of i in variable.c = %d", j);
}

Now, define the main function inside program1.c

#include<stdio.h>
#include "variable.c" //link program variable.c
int i; //exteranl global declaration
void show();
int main()
{
   i=10;
   show();
   printf("\nValue of i in program1.c = %d", i);
   return 0;
}

Output:-

Value of i in variable.c = 20
Value of i in program1.c = 10

Extern declaration within the same file

The extern declaration tells the compiler that there will be a variable x, somewhere in this file or in another file, and it will be a glocal variable.

#include<stdio.h>
extern int x;
int main()
{
   x=x+2;
   printf("x = %d",x);
   return 0;
}
int x=10;

Output:-

x = 12

Declaration part can be before or after the initialization part.

#include<stdio.h>
int x=10;
int main()
{
   x=x+2;
   printf("x=%d",x);
   return 0;
}
extern int x;

Declaration and initialization can be in the same lines. But it should be at top of the program that is before the using of the variable because the C program executed from top to bottom.

#include<stdio.h>
extern int x=5;
 int main()
 {
   x=x+2; //Valid
   printf("x=%d",x);
   return 0;
 }
#include<stdio.h>
int main()
 {
   x=x+2;
   //error: ‘x’ undeclared (first use in this function)
   printf("x=%d",x);
   return 0;
 }
 extern int x=10;

Note:- The extern variable must be initialized as a global variable.

#include<stdio.h>
extern int x;
int main()
{
   x = 5;
   x=x+2;
   printf("x=%d",x);
   return 0;
}
//undefined reference to `x'

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or you find anything incorrect? Let us know in the comments. Thank you!

Leave a Comment

Your email address will not be published. Required fields are marked *