Compiling a C Program: Behind the Scenes
We hit "Build", and seconds later, an executable appears. But what actually happens in that black box? The transformation from human-readable C code to machine-executable binary involves four distinct stages.
#include <stdio.h>
#define MAX 10
int main() {
printf("Hello, Silicon! count: %d\n", MAX);
return 0;
}
1. Preprocessing
The preprocessor (cpp) handles directives starting with #.
- Includes: The content of headers (
stdio.h) is pasted directly into the file. - Macros:
MAXis replaced with10. - Comments: Stripped out.
Command: gcc -E main.c -o main.i
2. Compilation
The compiler (cc1) translates the preprocessed code (.i) into Assembly
Language (.s). This is where syntax checking and optimization happen.
Command: gcc -S main.i -o main.s
3. Assembly
The assembler (as) translates assembly instructions into machine code (object code). The
output is a relocatable object file (.o)—it's binary code, but not yet executable.
Command: gcc -c main.s -o main.o
4. Linking
The linker (ld) combines your object file with standard libraries (like the implementation
of printf in libc). It resolves symbol references and arranges the final
memory layout to produce the actual executable.
Final Command: gcc main.o -o main