Storage Classes in C
Tags: c
Published: 2021-05-16 06:51:44

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:
<ul>
    <li> Scope, visibility, and life-time. </li>
    <li> Help us trace the existence of a particular variable during the run time of a program.</li>
</ul>

<hr/>

### What Storage Classes Does C Provide? 

C provides **4** storage classes: 
<ul>
    <li> auto </li>
    <li> extern </li>
    <li> static </li>
    <li> extern </li>
</ul>

These can be divided into **2** storage duration's:
<ul>
    <li> automatic storage duration </li>
    <li> static storage duration </li>
</ul>

<hr/>

### Auto Storage Class 

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

Why use Auto?
<ul>
    <li> Automatic storage is a way of conserving memory. We do not want every variable to be global.</li>
    <li> We only want to use these variables when absolutely necessary. </li>
</ul>

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;
}

```
<hr/>

### Extern Storage Class

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

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); };

```

<hr/>

### Static Storage Class

<ul>
    <li> The static storage class can be used on local and global variables and functions. </li>
    <li> 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). </li>
    <li> 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. </li>
    <li> When applied to functions, it instructs the function to only be able to be called from the same file where it appeared. </li>
</ul>

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(){
   static int value_two = 0;
   ++value_two;
   printf("%d\n", value_two);
}

```
<ul>
    <li> Here, we are seeing two different results. </li>
    <li> 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. </li>
    <li> 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. </li>
</ul>

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

<hr/>

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

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);
}

```