Bytebook Compiler

Functions

Scope & Storage Classes

Where variables live and how long they last: local, global and block scope, plus the auto, static, extern and register storage classes.

3 min read2 runnable examples4-question quiz

Every variable has a scope (where in the code its name can be used) and a lifetime (how long its memory exists). A storage class keyword controls both.

Local, global and block scope

C
#include <stdio.h>

int counter = 0;                 // global: visible in every function below

void visit(void) {
    counter++;                   // uses the global
    int local = 10;              // local: exists only during this call
    printf("visit: counter = %d, local = %d\n", counter, local);
}

int main(void) {
    visit();
    visit();
    int x = 1;
    {
        int x = 2;               // block scope: this x hides the outer x
        printf("inner x = %d\n", x);
    }
    printf("outer x = %d\n", x);
    return 0;
}
Output
visit: counter = 1, local = 10
visit: counter = 2, local = 10
inner x = 2
outer x = 1

When an inner variable has the same name as an outer one, the inner one shadows it inside its block.

The four storage classes

Storage class Where stored Default value Scope Lifetime
auto stack garbage block until the block ends
register CPU register (a hint) garbage block until the block ends
static data segment 0 block (or file) the whole program
extern data segment 0 global the whole program

auto

Every local variable is auto by default, so you never need to write the keyword.

static

A static local variable is created once and keeps its value between calls:

C
#include <stdio.h>

void countCalls(void) {
    static int calls = 0;   // initialised only once
    int normal = 0;         // re-created on every call
    calls++;
    normal++;
    printf("calls = %d, normal = %d\n", calls, normal);
}

int main(void) {
    countCalls();
    countCalls();
    countCalls();
    return 0;
}
Output
calls = 1, normal = 1
calls = 2, normal = 1
calls = 3, normal = 1

A static global variable or function is visible only inside its own .c file — a simple way to hide helpers from other files.

extern

extern declares a global variable that is defined in another file (or later in this one). It does not create new memory:

C
// file1.c
int total = 50;            // definition: memory is created here

// file2.c
extern int total;          // declaration: "total exists somewhere else"
void show(void) { printf("%d\n", total); }

register

register int i; asks the compiler to keep i in a CPU register for speed. Modern compilers ignore the hint and decide for themselves. You cannot take the address (&i) of a register variable.

Test yourself

4 questions · pick an answer to check it instantly

  1. 1

    What is the default initial value of a static int variable?

  2. 2

    A static local variable keeps its value...

  3. 3

    What does extern int count; do?

  4. 4

    Which storage class forbids taking the variable's address with &?