A storage-class specifier decides where a variable lives, how long it lives (lifetime) and who can see it (linkage).
| Specifier | Lifetime | Default value | Scope / linkage | Typical use |
|---|---|---|---|---|
auto (default for locals) | Until the block ends | Garbage | Block, no linkage | Ordinary local variables |
static (local) | Whole program | 0 | Block, no linkage | Remember a value between calls |
static (global / function) | Whole program | 0 | File only (internal linkage) | Hide helpers from other files |
extern | Whole program | 0 (where defined) | All files (external linkage) | Share a global across files |
register | Until the block ends | Garbage | Block | Historic hint; cannot take its address |
_Thread_local (C11) | Per thread | 0 | As above | One copy per thread |
static local: state that survives calls
#include <stdio.h>
int next_id(void) {
static int id = 0; /* initialised once, before the program starts */
int calls = 0; /* automatic: recreated on every call */
calls++;
id++;
printf("id=%d calls=%d\n", id, calls);
return id;
}
int main(void) {
next_id();
next_id();
next_id();
return 0;
}id=1 calls=1
id=2 calls=1
id=3 calls=1static at file level: private to the file
/* counter.c */
static int count = 0; /* invisible to other .c files */
static void log_change(void) { } /* helper, internal linkage */
void counter_increment(void) {
count++;
log_change();
}
int counter_value(void) { return count; }extern: one definition, many declarations
#include <stdio.h>
extern int shared; /* declaration: "defined somewhere else" */
void bump(void);
int main(void) {
bump();
bump();
printf("shared = %d\n", shared);
return 0;
}
int shared = 100; /* the one definition (normally in another .c file) */
void bump(void) { shared += 5; }shared = 110register
int main(void) {
register int i = 0;
int *p = &i; /* error: address of register variable requested */
return *p;
}Modern compilers ignore register for optimisation — they allocate registers far better than humans. Its only remaining effect is forbidding &. (auto in C means “automatic storage”; C23 repurposes it for type inference like C++.)
What are the differences between a static local variable and a global variable?
What does static mean for a function?
Can a static variable be initialised with a non-constant expression?