Compilation happens per-file: gcc -c file.c produces file.o, an object file containing compiled machine code plus a table of symbols it defines and symbols it needs from elsewhere. The linker then resolves those cross-references, combining every .o file into one executable — this is why a function must be DECLARED (via a header, typically) in any file that calls it, even though its actual DEFINITION lives in just one .c file elsewhere. static at file scope restricts a function or global variable's visibility to just its own file (internal linkage); without static, it's visible to every other file in the program by default (external linkage) — the opposite default from most modern languages.
A real 3-file project: header, implementation, and main
main.c never sees mymath.c's actual code — only the declarations in mymath.h. This separation is exactly what lets mymath.c be recompiled without touching main.c at all, when only its implementation changes.
#ifndef MYMATH_H
#define MYMATH_H
int add(int a, int b);
#endif#include "mymath.h"
int add(int a, int b) {
return a + b;
}#include <stdio.h>
#include "mymath.h"
int main(void) {
printf("%d\n", add(2, 3));
return 0;
}Compiling and linking separately
Each -c compiles ONE file to an object file without linking; the final command links both .o files together into one executable — exactly the sequence a Makefile automates.
$ gcc -c mymath.c // produces mymath.o
$ gcc -c main.c // produces main.o
$ gcc -o myapp main.o mymath.o // LINKS the two object files together
$ ./myappstatic: restricting a name to its own file
Without static, this internal() function would be visible (and callable) from any other file in the program by default — C's default linkage is the opposite of most modern languages, where privacy is opt-in rather than the baseline.
static void internalHelper(void) { // static: only visible within THIS file
// implementation detail, not part of this file's public API
}
void publicFunction(void) { // no static: visible to other files (via a header)
internalHelper();
}