Skip to Content
Course content

12: Storage Classes: auto, static, extern, register

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Think of your program's memory like a busy office space. Not every piece of information needs to be stored in the same way. Some things are just scribbles on a Post-it note that you toss in the trash the moment you finish a task. Other things are written on a whiteboard in a specific room; they stay there even if you leave the room and come back later. Then you have the company-wide bulletin board in the lobby—everyone in the building can see it, no matter which office they're in. Finally, there's the handheld calculator in your pocket; it's incredibly fast to access, but it can only hold one or two numbers at a time.

In C, storage classes are exactly that. They tell the compiler where to store a variable, how long it should live (lifetime), and who is allowed to see it (visibility/scope). Let's map those office tools to the actual keywords.

Ephemeral Notes and Permanent Whiteboards

Most variables you've written so far are auto. In fact, if you don't specify a storage class for a local variable, C assumes it's auto. Like a Post-it note, an auto variable is created when the function starts and is destroyed the second the function returns. It's "automatic" memory management at its simplest.

Now, static is where things get interesting. A static local variable is like that whiteboard. It's still only visible to the function it's in, but it doesn't disappear when the function ends. It remembers its value for the entire duration of the program. I use this all the time when I need a function to keep track of its own state without cluttering the global namespace.

#include <stdio.h>

void track_calls() {
    auto int local_count = 0;      // Re-initialized to 0 every time
    static int static_count = 0;   // Initialized once, persists between calls

    local_count++;
    static_count++;

    printf("Local: %d, Static: %d\n", local_count, static_count);
}

int main() {
    track_calls(); // Local: 1, Static: 1
    track_calls(); // Local: 1, Static: 2
    track_calls(); // Local: 1, Static: 3
    return 0;
}

The Company Bulletin Board

When your project grows beyond a single .c file, you'll run into a problem: how does file_a.c access a variable defined in file_b.c? This is where extern comes in. It's the company bulletin board.

The key thing to remember here is that extern is a declaration, not a definition. You aren't telling the compiler to "create a new variable"; you're telling it, "Somewhere else in this project, a variable with this name and type already exists. Go find it."

If you define int global_score = 100; in one file and put extern int global_score; in another, both files are now looking at the exact same spot in memory. Just be careful—overusing extern turns your code into a tangled web of dependencies that's a nightmare to debug. Use it sparingly.

The Pocket Calculator

Finally, we have register. This is a hint to the compiler that you'll be using this variable a lot and it should be stored in a CPU register instead of RAM for lightning-fast access. It's like keeping a number in your head or on a handheld calculator rather than walking across the room to check the whiteboard.

Here's the catch: register is just a suggestion. Modern compilers are actually much better at optimizing register allocation than we are, so they often ignore this keyword entirely. Also, because a register isn't a memory address, you cannot use the & (address-of) operator on a register variable. If you try, the compiler will throw an error.




📋 Practical Task

Exercise: Persistent Session Tracker for a Game Menu

You are building a simple game menu system. You need to track two different things: the total number of times the "Settings" menu has been opened during the entire game session, and a global "Game Difficulty" level that can be accessed by different parts of the program.

Requirements:

  • Create a function void open_settings_menu(). Inside this function, use a static variable to keep track of how many times the menu has been opened. Each time the function is called, increment the counter and print: "Settings menu opened X times".
  • In your main file, define a global variable int game_difficulty = 1;.
  • Create a second separate function (simulating a different module) called void print_difficulty(). Use the extern keyword within this function's scope (or above it) to access and print the game_difficulty variable.
  • In main(), call open_settings_menu() three times and call print_difficulty() once to verify everything is working as expected.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.