📘 Lesson  ·  Lesson 59

Storage Classes

What is a storage class?

When you declare a variable in C, the compiler needs to know more than just its type. It needs to know where the variable can be used, how long it should stay alive in memory, and what value it starts with if you do not set one. A storage class answers exactly these three questions.

So every variable has three properties tied to its storage class:

  • Scope — the region of code where the variable is visible.
  • Lifetime — how long the variable exists in memory.
  • Default value — what it holds if left uninitialised.

C gives you four storage-class keywords to set these: auto, register, static and extern.

The four storage classes at a glance

KeywordIn one line
autoThe automatic default for every local variable.
registerA hint to keep the variable in a fast CPU register.
staticKeeps its value between function calls; also hides globals in a file.
externRefers to a global variable defined in another file.

Now let's look at each one with a working example.

auto — the default local

Any variable you declare inside a function is automatically auto. Writing the keyword is optional and adds nothing — which is why you almost never see it in real code.

C Language
#include <stdio.h>
int main() {
    auto int x = 10;   // same as: int x = 10;
    int y = 20;        // y is also auto by default
    printf("x = %d, y = %d\n", x, y);
    return 0;
}
Output:
x = 10, y = 20
💡 Note

An auto variable is created when the block starts and destroyed when the block ends. Its default value is garbage — always initialise it.

register — a speed hint

The register keyword requests that a variable be kept in a CPU register instead of RAM, which is faster to access. It is only a request: the compiler may ignore it. A common use was tight loop counters.

C Language
#include <stdio.h>
int main() {
    register int i;
    for (i = 1; i <= 3; i++)
        printf("%d ", i);
    return 0;
}
Output:
1 2 3
⚠️ Important

You cannot take the address of a register variable — &i is an error. Modern compilers optimise so well that register is effectively obsolete today.

static — remembers its value

This is the most useful storage class. A static local variable is initialised only once and keeps its value across function calls, because its lifetime is the whole program — not a single call.

C Language
#include <stdio.h>
void counter() {
    static int count = 0;   // set once, survives calls
    count++;
    printf("Call number: %d\n", count);
}
int main() {
    counter();
    counter();
    counter();
    return 0;
}
Output:
Call number: 1
Call number: 2
Call number: 3

If count were an ordinary local variable, it would reset to 0 on every call and always print 1. Being static is what lets it count.

💡 Extra use

A global variable marked static becomes private to its file — other files cannot access it with extern. This is a clean way to hide internal helpers.

extern — shared across files

Large programs are split across several .c files. When one file needs a global variable that is defined in another file, it uses extern to say "this exists elsewhere, trust me."

file1.c
#include <stdio.h>
int score = 100;        // actual definition

void show(void);        // from file2.c

int main() {
    show();
    return 0;
}
file2.c
#include <stdio.h>
extern int score;       // declared here, defined in file1.c

void show(void) {
    printf("Score = %d\n", score);
}
Output:
Score = 100
💡 Rule of thumb

extern only declares — it never allocates memory. Exactly one file must actually define the variable (here, file1.c).

Scope, lifetime & default value

Storage classScopeLifetimeDefault value
autoLocal (block)Until block endsGarbage
registerLocal (block)Until block endsGarbage
staticLocal or fileWhole program0
externGlobal (all files)Whole program0

Common mistakes

  • Expecting an ordinary local variable to remember its value between calls — you need static for that.
  • Trying to take the address of a register variable with &.
  • Using extern and also initialising the variable in the same line in every file — only one file should define it.
  • Assuming auto variables start at 0 — they hold garbage until initialised.
🏋️ Practice

Write a function int nextId() that returns 1, 2, 3, … on successive calls using a static counter. Then try removing static and observe how the output changes.

Summary

  • A storage class sets a variable's scope, lifetime and default value.
  • auto is the default for locals — you never need to write it.
  • register hints at CPU-register storage; it is obsolete today.
  • static keeps a local's value across calls, and hides globals inside a file.
  • extern lets one file use a global defined in another file.

Frequently Asked Questions

What do storage classes actually control in C?
A storage class controls three things about a variable: its scope (where it is visible), its lifetime (how long it stays in memory), and its default value if you do not initialise it. The four storage classes are auto, register, static and extern.
Is auto ever needed in modern C?
Almost never. Every local variable is auto by default, so writing the keyword adds nothing. In C++11 and later auto means something completely different (type deduction), so in practice you simply never type auto in C.
Why does a static local variable keep its value between calls?
Because a static variable is created once, before the program starts, and lives for the entire run of the program — not just during one function call. The function can see it only inside its own body (local scope), but the value survives after the function returns, so the next call continues from where it left off.
What is the difference between static and extern?
Both affect how a variable is shared, but in opposite ways. extern tells the compiler a global variable is defined in another file so this file can use it. static at file level does the reverse — it hides a global variable so other files cannot see it.
Does register actually make my program faster?
Rarely. register is only a suggestion to keep a variable in a CPU register, and modern compilers already make far better decisions than the hint. You also cannot take the address of a register variable with &. In real code it is effectively obsolete.
← Back to C Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.