A strong answer
In C, every identifier has two independent properties: storage duration (how long its memory exists at runtime) and linkage (whether its name is visible to the linker across multiple .c translation units). The static keyword changes different properties depending on where it is written:
- Inside a function (
static int count = 0;): It changes storage duration from automatic (stack) to static. Instead of being created on the stack on each call and destroyed on return,countis allocated once in the binary's.dataor.bsssegment beforemainstarts and retains its value across all calls to that function, while keeping block scope (no other function can accesscountby name). - At file scope (
static int helper(void)orstatic int config;): File-scope variables already have static storage duration; herestaticchanges linkage from external to internal. The symbol is kept private to that single.ctranslation unit so the linker will not export it, preventing name collisions with other.cfiles and allowing the compiler to aggressively inline or dead-code-eliminate it.
By contrast, extern declares that a variable or function has external linkage and its storage is defined in another translation unit (e.g., extern int global_errno; in a header tells the compiler the type of global_errno without allocating duplicate storage for it).
What the interviewer is listening for
- Clearly separates scope (where in source text a name can be referenced), storage duration (lifetime in memory: stack vs
.data/.bss), and linkage (internal vs external visibility told). - Explains both uses of
static(persistent local state vs private file-scope module encapsulation). - Mentions that uninitialized
staticand global variables live in.bssand are guaranteed by the C standard to be zero-initialized beforemainruns.
Common mistakes
- Believing a local
staticvariable is re-initialized every time the function is called (its initializer is a compile-time constant placed in.data/.bssonce at program startup). - Using a local
staticvariable inside a function called by multiple threads without synchronization, creating a data race on the shared.data/.bssslot. - Omitting
staticon private helper functions in.cfiles, polluting the global linker namespace.