Storage Classes in C

In this article, I will go over the four storage classes in C: auto, extern, static and register. I will explain how to use them and the specifics of each storage class.

What is a Storage Class?

A storage class is a way to describe the features of a variable or function.

This includes:

  • Scope, visibility, and life-time.
  • Help us trace the existence of a particular variable during the run time of a program.

What Storage Classes Does C Provide?

C provides 4 storage classes:

  • auto
  • extern
  • static
  • extern

These can be divided into 2 storage duration's:

  • automatic storage duration
  • static storage duration

Auto Storage Class

  • The keyword auto is used to declare variables of automatic storage duration.
  • It means it is a local variable.
  • Every local variable created, is implicitly 'auto'
  • Created when the block in which they are defined is entered.
  • Destroyed when the block is exited.

Why use Auto?

  • Automatic storage is a way of conserving memory. We do not want every variable to be global.
  • We only want to use these variables when absolutely necessary.

Example 1

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[]){
    auto int age = 23; // same as int age = 23;
    printf("%d\n", age);

    return EXIT_SUCCESS;
}

Extern Storage Class

  • The extern storage class simply tells us that a variable is defined somewhere else.
  • We are telling the compiler "Hey, don't freak out. The variable is defined somewhere else and I am gonna use it.
  • The main purpose of using extern variables is that they can be accessed between different source files in a large program.
  • Functions contained in separate files can communicate through extern variables.
  • Functions are implicitly 'extern' as well.

Example 1

main.c

#include <stdio.h>
#include <stdlib.h>

extern int x;
extern int b;
extern void print_x();
extern void print_b();

int main(int argc, char * argv[]){
    print_x(); //32
    print_b(); //8

    x = 50;
    b = 99;

    print_x(); //50
    print_b(); //90

    return EXIT_SUCCESS;
}

extern.h

int x;
int b;
void print_x();
void print_b();

extern.c


int x = 32;
int b = 8;

void print_x() { printf("%d\n", x); };

void print_x() { printf("%d\n", b); };

Static Storage Class

  • The static storage class can be used on local and global variables and functions.
  • When applied to local variables, it instructs the compiler to keep the variable alive during the lifetime of the program (just like a global variable).
  • When applied to global variables, it instructs the global variable to only be able to be used/accessed in that file that it was declared in.
  • When applied to functions, it instructs the function to only be able to be called from the same file where it appeared.

Example 1

#include <stdio.h>
#include <stdlib.h>

void print_and_increment();

void print_and_increment_with_static();

int main(int argc, char * argv[]) {
    print_and_increment(); //1
    print_and_increment(); //1

    print_and_increment_with_static(); //1
    print_and_increment_with_static(); //2


}

void print_and_increment(){
    int value_one = 0;
    ++value_one;
    printf("%d\n", value_one);
}

void print_and_increment_with_static(){
   int value_two = 0;
   ++value_two;
   printf("%d\n", value_two);
}
  • Here, we are seeing two different results.
  • The variable value_one only exists within the block of the function print_and_increment. When it leaves the scope, the variable is destroyed. No matter how many times we call it, we will get the same result.
  • The variable value_two is static. Therefore, it exists throughout the entire program. It is not local. Every time we call it, the value changes.

NOTE: Static variables should not be declared inside a struct. The C compiler requires the entire struct element to be placed together.


Register Storage Class

  • A processor register is a local storage space within the CPU that holds instructions, storage addresses, or any kind of data.
  • The register storage class is used to define local variables that should be stored in the register instead of the RAM
  • Makes the use of register variables faster than variables stored in RAM.
  • The keyword 'register' suggests to the compiler to put the variable inside the register.
  • Sometimes the compiler will listen, other times it wont. It is largely dependent on hardware and implementation restrictions.
  • Generally, the compiler will do it by itself regardless if you use this keyword or not.
  • You can not get the address of a register variable.
  • Register variables have the same life-span as an auto variable(local variable).
  • Therefore, register variables can not be declared globally, only locally.

Example 1


#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[]) }
    register int age = 23;

    printf("Your age is %d\n", age);
}