Storage classes in C

Storage class in C or class in C are identifier or variable types defines unique characteristics and scope of a variable. Storage class or class does not have any relation with the class keyword used in C++ programming. There are mainly five types of storage classes available in C and they are -

  • Global storage class
  • Static storage class
  • Automatic storage class
  • Register storage class
  • External storage class

Global storage class in C

Global- As the name suggests, global variable can be accessed universally. There is no need to give this keyword if we declare a variable outside function brackets. The visibility of a global variable starts from the next line of the declaration and can be accessed throughout the file. Life of a global variable is till the program ends. Global variables are by default zero if not initialized. Global variable sometimes get extended with extern to export to be used by external modules or files.

int gInt;
int main (int argc, char * argv[])
..

Global storage class example

We have below example to show the syntax of global storage class identifier and the scope of the variable. We are displaying the "gInt" variable in main() and chagning the value from a function named as change_global(). This demo shows the initial value of globals are zero (0) and they can be accessed from main and any functions in the source file.

#include <stdio.h>

/* Global storage class */
int gInt;

void change_global (void)
{
  printf ("Enter the value of gInt : ");
  scanf ("%d", &gInt);
}

int main (int argc, char * argv[])
{
  printf ("Global variable gInt is initially %d\n", gInt);

  /* Change the global */
  change_global();

  printf ("Global variable gInt is now %d\n", gInt);
  return 0;
}

Note: gInt is declared in the top of the file so any funtion below can view this variable. If it is declared below change_global() then gInt can not be referanced in change_global(). Compiler will not be able to lookup the symbol definition and produce an undeclared identifier error.

Output

$ gcc global.c -o global
$ ./global 
Global variable gInt is initially 0
Enter the value of gInt : 20
Global variable gInt is now 20
$ 

Static storage class in C

Static - Scope of a static variable is local to module/file if declared in file scope or scope will be local to the function if declared inside a function. Life of a static variable is till the program ends. Global and static both are linked in .DATA or .BSS area but in case of static linker never exposes these variables to outside. Static variables are by default zero if not initialized.

Static storage class example

We have below demo source to show the syntax of static storage class identifier and the scope of the variable. We have declared "sInt" variable in change_static() and chagning the value of this static variable from the same function. This demo shows the initial value of statics are zero (0) and they can be accessed only from local scope of change_static(). Even if the change_static() function exists in main(), the value of "sInt" retains the older modified value and it remains till program exits.

#include <stdio.h>

void change_static (void)
{
  /* Static storage class */
  static int sInt;

  printf ("Current value of sInt : %d\n", sInt);
  printf ("Enter the value of sInt : ");
  scanf ("%d", &sInt);
}

int main (int argc, char * argv[])
{
  /* display and change the static */
  change_static();

  /* display and change the static */
  change_static();

  /* display and change the static */
  change_static();

  return 0;
}

Note: "sInt" is declared inside change_global() function. So the visibility of this static variable is limited to function scope. However this can be declared in global scope of static.c with static. That will make the variable only visible to file scope of static.c. Compiler and linker will not be able to reference this variable to other source files in the project.

Output

$ gcc static.c -o static
$ ./static 
Current value of sInt : 0
Enter the value of sInt : 10
Current value of sInt : 10
Enter the value of sInt : 20
Current value of sInt : 20
Enter the value of sInt : 30 
$

Automatic storage class in C

Automatic - Since the type is named as automatic, this keyword is not needed before a variable. A variable declared as a local scope or declared in a function can be treated as automatic. Life time of an automatic variable in only till the function ends and also the visibility is only inside the function or section. Automatic variable are linked to take the memory in current stack area and can have any value if not initialized.

Automatic storage class example

We have declared an auto variable add_two() to hold the result of the addition and then returned the function. The initial value is any random value and upon return the variable will be out of scope.

#include <stdio.h>

int add_two (int x, int y)
{
  /* Automatic storage class*/
  auto int z;

  z = x + y;
  return z;
}

int main (int argc, char *argv[])
{
  printf ("1 + 2 = %d\n", add_two(1, 2));
  return 0;
}

Output

$ gcc auto.c -o auto
$ chmod 777 auto
$ ./auto
1 + 2 = 3
$

Register storage class in C

Register - Register keyword tells compiler to keep this variable in one of register of CPU to optimize execution time. This keyword never ensures that this will be done. If there are free registers available to hold this variable then only the variable can be treated as register type. Only automatic variables can be optimized as Register type. Global/extern/static cannot be optimized with register.

Register storage class example

We have declared an register variable power(). Variable R is accessed n number of times in the function. It is accessed and modified n times. There will be having less effect when n is of low. A large value will have performace effect. Making this R to register will redude the memory access and it will enhance the runtime performance. The initial value is any random value and upon return the variable will be out of scope.

#include <stdio.h>

int power (int x, int n)
{
  int I;
  /* Register storage class */
  register int R;
  
  R = x;
  for (= 1; I < n; I++)
  {
    R = R * x;
  }
  return R;
}

int main (int argc, char *argv[])
{
  int I, P;
  for (= 0; I < 5; I++)
  {
    printf ("=================\n");
    for (= 0; P < 5; P++)
    {
      printf ("%d ^ %d = %d\n", I, P, power(I, P));
    }
  }
  return 0;
}

Output

$ gcc register.c -o register
$ ./register 
=================
0 ^ 0 = 0
0 ^ 1 = 0
0 ^ 2 = 0
0 ^ 3 = 0
0 ^ 4 = 0
=================
1 ^ 0 = 1
1 ^ 1 = 1
1 ^ 2 = 1
1 ^ 3 = 1
1 ^ 4 = 1
=================
2 ^ 0 = 2
2 ^ 1 = 2
2 ^ 2 = 4
2 ^ 3 = 8
2 ^ 4 = 16
=================
3 ^ 0 = 3
3 ^ 1 = 3
3 ^ 2 = 9
3 ^ 3 = 27
3 ^ 4 = 81
=================
4 ^ 0 = 4
4 ^ 1 = 4
4 ^ 2 = 16
4 ^ 3 = 64
4 ^ 4 = 256
$ 

External storage class in C

External variables are those global variables with extern type so that it can be accessed by external or third party modules. Life, scope and default un-initialized value of extern variable is same as global. Life is till program ends and scope is global or external.

Extern storage class example

We have below example to show the syntax of extern storage class identifier and the scope of the variable. We have a gInt variable declared as extern in main.c. gInt is actually defined as global in extern.c file. Main.c can access and modify this global gInt located in extern.c with the help of extern keyword. Extern keyword actually do not create a global variable but tells the compiler to reference the variable externally. Linker resolves the actual address of the symbol during linking these two files. This demo shows the initial value of extern is zero (0) and they can be accessed from two different files.

/* main.c */
#include <stdio.h>

/* Extern storage class */
extern int gInt;
void change_extern (void);

int main (int argc, char *argv[])
{
  
  printf ("initial value of extern gInt %d\n", gInt);
  change_extern ();
  gInt = 5;
  change_extern ();
  printf ("current value of extern gInt %d\n", gInt);
  return 0;
}

/* extern.c */
#include <stdio.h>

/* Global storage class */
int gInt;

void change_extern (void)
{
  printf ("change_extern: current value of extern gInt %d\n", gInt);
  gInt = 10;
  printf ("change_extern: changed value of extern gInt %d\n", gInt);
}

Note: An extern variable is actually an alias of a global variable. To access this one global variable from other files extern keyword should be used in other files. Extern should not be used in original file where the variable is declared. Here gInt is declared in extern.c. Extern keyword should not be used here. When there is no defined global variable in any module, compiler will pass but linker will produce linker error. When entern keyword is not used in any module then they will create multiple definition of global variable. Linker will fail saying multiple definition and through out error as symbol already defined in obj.

Output

$ gcc -c extern.c -o extern.o
$ gcc main.o extern.o -o extern
$ chmod 777 extern
$ ./extern 
initial value of extern gInt 0
change_extern: current value of extern gInt 0
change_extern: changed value of extern gInt 10
change_extern: current value of extern gInt 5
change_extern: changed value of extern gInt 10
current value of extern gInt 10
$ 

We have summarize above discussion in a single table as below

Class ScopeInit ValueLife
Global storage classUniversalZeroTill Program exits
Static storage classLocal to function/fileZeroTill Program exits
Automatic storage classLocal to functionany randomTill Function exits
Register storage classLocal to functionany randomTill Function exits
Extern storage classUniversal and external modulesZeroTill Program exits

About our authors: Team EQA

You have viewed 1 page out of 252. Your C learning is 0.00% complete. Login to check your learning progress.

#