Storage class in C

In C language, each variable has a storage class which decides the following things:

  • Scope: where the variable is accessible in the program.
  • Initialization value: default value without initialization
  • Lifetime: how long the variable exists.

C we have four storage classes:

For better understanding, please refer to the topics below:

Automatic variable: auto

  • Scope: They have scope within the function block in which they are defined.
  • Lifetime: Variables defined with auto storage class have a lifetime until the end of the function/method block in which they are defined.
  • Default initial value: They are initialized to garbage value by default by the compiler.
  • The default storage class for any local variable is auto.
  • These variables are allocated automatically at run time.
  • They are automatically freed upon exiting the block.
  • They are preceded by keyword auto. Example: auto int i
  • They are stored in the stack section of memory.

Static Keywords: static

  • Scope: They have scope within the function block in which they are defined.
  • Lifetime: Until the whole program does not finish execution.
  • Default initial value: They are initialized to 0 by default by the compiler.
  • This storage class is like telling the compiler that this variable is needed throughout the lifetime of the program, unlike the local variable which goes out of scope upon exiting from the block.
  • They can be initialized only once but can be declared multiple times.
  • They are stored in the data section of memory.

This keyword in C can be associated with three entities:

  • Local variable
  • Global variable
  • Function

Local variable:

If any local variable is declared static, it means it can retain its value during multiple function calls that are maintaining its state between the flow controls, unlike the local variable which goes out of scope upon exiting from the block.

Static local variables are useful in co-routines (re-entrant function) where we have two routines/functions and flow control is cooperatively passed to each other without returning.

Example:

Read and parse the file:

We have one routine which reads a few characters from the file and sends them to the second routines which are responsible for parsing. Once the parsing is done again the control goes back to the first routine which does the reading and resends new data for parsing.

However, the routine responsible for reading must maintain its previous state that is from which characters to read in a new cycle. Thus we can use a static variable that can maintain its state between the flow control among reading and parsing routines.

Global Variable:

If there is any static global variable, it means that the variable is accessible only to that file, and cannot be used in another file using the extern keyword.

Static function:

If any function is made static, it means again that a particular function cannot be accessed outside that file, making that function an extern.

By default, all functions can be accessed outside the file, no need to make it extern.

Another use is that we can use the same function name in two different files. By making any function static, since its scope is restricted to the same file (internal linkage), thus we can have the same function name.

With static variableWithout static variable
#include <stdio.h>

void fun ()
{
static int a = 0;
a = a + 10;
printf (“\n The value of a is: %d\n”,a);
}

int main ()
{
fun();
fun();
fun();
return 0;
}
#include <stdio.h>

void fun ()
{
int a = 0;
a = a + 10;
printf (“\n The value of a is %d\n”, a);
}

int main ()
{
fun ();
fun ();
fun ();
return 0;
}
Output:
The value of a is: 10
The value of a is: 10
The value of a is: 20


Output:
The value of a is: 10
The value of a is: 10
The value of a is: 10

Extern keyword: extern

  • The extern keyword is used with a variable to inform the compiler that this variable is defined somewhere else.
  • It does not allocate any storage/memory for the variables.
  • The extern variable can be initialized outside the block that should be global. This variable or function has an external linkage that is defined somewhere else in the program or all together in a new file.
  • They are stored in the data segment of the memory.

Extern variable within the same file

#include <stdio.h>
/* Global variable "a" defined */
int a;
int main()
{
  /* This is just a declaration, no memory allocated */
  extern int a;
  printf("\n The value of a is : %d\n",a);
  return 0;
}

Output:
The value of a is :0

Extern variable in different file

file1.cfile2.c
#include <stdio.h>

/* Global variable “a” defined and initialized */
int a = 7;
int main()
{
fun1();
printf (“\n The value of a is:%d\n”,a);
return 0;
}
#include <stdio.h>
#include “file1.c”

/* extern variable, just declared */
extern int a;

void fun1 (void)
{
a = a + 10;
printf (“\n The value of a is:%d\n”,a);
}

Output:

[aprakash@wtl-lview-6 packetlogic2]$ gcc file1.c file2.c</p>
[aprakash@wtl-lview-6 packetlogic2]$ ./a.out

The value of a is: 17
The value of a is: 17

By default all the functions have external linkages, that’s the reason we do not explicitly make the function fun1() in the first program as extern.

Note:

  • extern int a; just declared not defined
  • extern int a = 10 ; both declared and defined.

GOOD USE CASE:

One use of extern can be in the case of mutex variable, such that it needs global access that is required by many files then in one of the files it can be defined (initialized) and with the help of extern can be accessed in other files too.

Register variable:

  • Scope: They have scope within the function block in which they are defined.
  • Lifetime: Variables defined with register storage class have a lifetime until the end of the function/method block in which they are defined
  • Default initial value: They are initialized to garbage value by default by the compiler.
  • Register variables are stored in the register of the CPU and not in the memory.
  • Accessing a variable stored in the register is faster than accessing the variable stored in memory.
  • All the variables cannot be stored in the register as there is a limited set of CPU registers.
  • It is most advantageous to use a register for storing pointers. If we use a normal variable then the compiler will fetch the address in the first CPU cycle and then in the second cycle, it goes to that particular address in the main memory. Thus, using the register saves the CPU cycle.
  • Since the register variables are not stored in memory, we cannot use the unary(&) operator on them. Unary operators are used to fetch memory addresses.
  • Example : register int

What storage classes are to be used when:

Speed and memory are two important metrics to determine the performance of the program. Hence the storage class of each variable should be appropriate to optimize the performance of the program. The following points should be taken into consideration while using the storage class.

  • Static storage class should be used only when the previous state of the variable needs to persist during the function calls.
  • The register storage call should be used with variables that are used very frequently but there is limited register available so should be used carefully.
  • Static global variables to be used when the variables need to be used by most of the functions in the program but not outside the file.
  • If there is no purpose as mentioned above, we should use an automatic storage class.


Categories: C Language

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: