Introduction

In C, storage classes define the lifetime, scope, default value and visibility of variables. They specify where a variable is stored, how long its value is retained, and how it can be accessed which help us to trace the existence of a particular variable during the runtime of a program.

Note: To use these storage classes, specify them before datatype declaration.

There are 4 primary storage classes:
1. auto
2. static
3. register
4. extern

1. auto

This is the default storage class in C. It’s scope is limited to a block of code i.e. a function or a conditional or looping structure. The auto keyword is abstracted by the compiler, hence there is no need to manually specify auto before every declaration.

Properties of auto Variables:

  • Scope: Local
  • Default Value: Garbage Value
  • Memory Location: RAM
  • Lifetime: Till the end of its scope
#include <stdio.h>
 
int main() {
  
    // auto is optional here, as it's the default storage class
    auto int x = 10;  
    printf("%d", x);
    return 0;
}

2. static

The static storage class makes a value in a block, persist even after its EOS (End of scope). It’s scope is still limited to a code block, but the latest value can be used by accessing/executing it again. Another use case would be limiting the defined variable or function to the current block of code. i.e. It prevents linking of a value/function externally.

Properties of static Storage Class:

  • Scope: Local
  • Default Value: Zero
  • Memory Location: RAM
  • Lifetime: Till the end of the program
#include <stdio.h>
void counter() {
  
    // Static variable retains value between calls
    static int count = 0;  
    count++;
    printf("Count = %d\n", count);
}
int main() {
  
    // Prints: Count = 1
    counter();  
  
    // Prints: Count = 2
    counter(); 
    return 0;
}

3. register

The register storage class is similar to the auto class in majority of its properties except for memory location. The register class tries to load the variable into a CPU register. CPU registers being the fastest of all memory options outperform memory access from RAM. But, the compiler may or may not obey this keyword everytime. It decides whether to load the variables into registers or not, based on availability of registers.

Cannot use & (address-of) operator with it.

Properties of register Storage Class Objects:

  • Scope: Local
  • Default Value: Garbage Value
  • Memory Location: Register in CPU or RAM
  • Lifetime: Till the end of its scope
#include <stdio.h>
 
int main() {
  
    // Suggest to store in a register
    register int i;  
    for (i = 0; i < 5; i++) {
        printf("%d ", i);
    }
    return 0;
}

4. extern

The extern storage classes refers to linking variables or functions from other blocks (files). It simply tells us that the variable is defined elsewhere and not within the same block where it is used. Functions are extern by default, so we have a choice to use extern keyword.

Properties of extern Storage Class Objects:

  • Scope: Global
  • Default Value: Zero
  • Memory Location: RAM
  • Lifetime: Till the end of the program.

extern_src.c

#include <stdio.h>
 
int ext_var = 86;
 
void say_hello() {
        printf("hello linker\n");
}

extern_main.c

#include <stdio.h>
 
// Link external variable
extern int ext_var;
 
// Link external function
void say_hello();
 
int main() {
        printf("External variable: %d\n", ext_var);
        say_hello();
        return 0;
}