Lesson content
Read, practise, then check your understanding
Storage-class specifiers help describe an identifier’s storage duration and linkage. These concepts are distinct:
- Scope: where the name is visible.
- Storage duration: how long its object exists.
- Linkage: whether declarations in different scopes or translation units name the same entity.
auto
Block-scope variables are auto by default. They have automatic storage duration: their lifetime begins when execution enters the block and ends when it leaves.
void process(void) {
auto int attempts = 0; // explicit auto is valid but rarely written
}
An uninitialized automatic object has an indeterminate value.
static
At block scope, static gives static storage duration while retaining block scope. Initialization occurs once before normal program execution, and the value persists across calls.
unsigned next_id(void) {
static unsigned current = 0;
return ++current;
}
This function is not thread-safe without synchronization and hides global state behind a narrow scope.
At file scope, static gives a name internal linkage, keeping a function or object private to its translation unit:
static void normalize_record(struct Record *record);
static const int default_limit = 100;
extern
extern declares an object or function defined elsewhere. Put one declaration in a header and exactly one object definition in a source file.
// metrics.h
extern unsigned long request_count;
// metrics.c
unsigned long request_count = 0;
Prefer accessor functions over exported mutable global objects when invariants or concurrency matter.
register
register historically suggested fast register storage for an automatic variable and prevents taking its address. Modern optimizers perform register allocation better than manual hints; the specifier is obsolete or removed in newer language evolution and should generally be avoided.
Thread storage
C11 provides _Thread_local for one instance per thread, subject to implementation support. Thread-local state can simplify context access but complicates testing and lifecycle reasoning.
Choose storage based on required lifetime and visibility, not convenience. Narrow scope and internal linkage reduce accidental coupling.
Knowledge check
Answer every question correctly to complete this chapter.
0 of 10 checks passed
Your progress is saved on this device.