A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
A global variable without static has external linkage: every file in the program can see and modify it. A global variable with static has internal linkage: it is visible only within the file where it is declared. Other files cannot reference it, even with an extern declaration. This is encapsulation at the file level. It prevents name collisions across modules and it prevents other modules from depending on your internal state. Use static on every global that is not part of the module's public interface.
/* counter.c */#include <stdio.h>static int call_count = 0;int public_value = 42;void increment(void) {call_count++;printf("increment called %d times\n", call_count);}int get_count(void) {return call_count;}
/* main.c */#include <stdio.h>extern int public_value;extern int call_count;void increment(void);int get_count(void);int main(void) {increment();increment();printf("public_value: %d\n", public_value);printf("count via getter: %d\n", get_count());printf("count direct: %d\n", call_count);return 0;}
The linker cannot find call_count. It is static in counter.c, which means it has internal linkage. It does not appear in the object file's symbol table as an exported symbol. The extern declaration in main.c promises that the symbol exists somewhere, but the linker cannot resolve it. public_value, which is not static, links fine. The fix: remove the extern call_count declaration and use the get_count accessor.
In a project with fifty source files, global names collide. Two files both declare static int buffer_size and there is no conflict. Without static, the linker reports a duplicate symbol error. Static globals give each file its own private namespace. They also enforce information hiding: if call_count is static, no other module can modify it directly. They must go through get_count and increment. The module controls its own state.
Static globals are the C equivalent of private module-level variables. Use them by default. Only expose a global without static if it is genuinely part of the module's public API. Next: static functions, which apply the same file-scope restriction to functions.
Finish the lesson once you have worked through the material. This awards ★ 30 XP.