5.1.1C Programming

C compilation — preprocessor, compiler, assembler, linker

1,863 words8 min readdifficulty · medium

WHY does compilation have stages?

A CPU only understands raw bytes (opcodes). C source is full of human niceties: #include, macros, comments, names like main, printf. The gap is huge, so we divide and conquer — each tool solves ONE sub-problem:

  • Preprocessor → handles text substitution (#-directives).
  • Compiler → translates real C into assembly for your CPU.
  • Assembler → turns assembly into machine code (an object file).
  • Linker → stitches object files + libraries into one executable.

Figure — C compilation — preprocessor, compiler, assembler, linker

Stage 1 — The Preprocessor (cpp)

WHAT it does:

  • #include <stdio.h>literally pastes the entire contents of that header file in place.
  • #define PI 3.14macro: replaces every PI token with 3.14.
  • #ifdef / #ifndef / #endif → conditional compilation (include code only if a macro is defined).
  • Strips all comments.

HOW to see it:

gcc -E hello.c          # output stops after preprocessing

Stage 2 — The Compiler (cc1)

WHAT it produces: a .s text file of human-readable assembly mnemonics (mov, add, call).

HOW to see it:

gcc -S hello.c          # produces hello.s

Stage 3 — The Assembler (as)

WHAT an object file contains:

  • Machine code for your functions.
  • A symbol table listing names defined here (e.g. main) and names needed but not yet found (e.g. printf) — marked as undefined.

HOW to see it:

gcc -c hello.c          # produces hello.o (not runnable yet!)

Stage 4 — The Linker (ld)

WHAT it solves:

  • Matches each undefined symbol (printf) to its defined location in libc.
  • Merges all code/data sections and assigns final memory addresses.
  • Adds startup code (_start) that calls main.

Forecast-then-Verify

Recall Predict the output of each flag

before reading gcc -E ::: preprocessed source (.i) gcc -S ::: assembly (.s) gcc -c ::: object file (.o), no linking gcc (no flag) ::: full executable Stopped after each? Verify by running them on a tiny file.


Common Mistakes (Steel-manned)


Mnemonic


Feynman: explain to a 12-year-old

Recall Click to read

Imagine writing a recipe to give to a robot chef who only understands button-presses.

  1. Preprocessor = your assistant who pastes in any borrowed recipe pages you referenced ("see the cake recipe") and copies out shorthand you defined.
  2. Compiler = translates your English recipe into the robot's step-by-step instruction language.
  3. Assembler = turns those instructions into the exact button-press codes the robot reads.
  4. Linker = if your recipe says "use Grandma's frosting," it goes and grabs Grandma's frosting steps and staples them in, so the robot has everything in one complete booklet it can run start to finish.

Active-Recall Flashcards

What are the 4 stages of C compilation in order?
Preprocessor → Compiler → Assembler → Linker
Which stage handles #include and #define?
The preprocessor (text substitution, before real compilation)
What does the compiler output?
Assembly language (.s), specific to the target CPU
What does the assembler output and what's special about it?
An object file (.o) with machine code + a symbol table containing undefined references
Why can't you run a .o file directly?
It has unresolved symbols (e.g. printf) and no entry-point setup; the linker must resolve them first
Which stage produces an "undefined reference" error?
The linker — a needed symbol's definition was never found
Do header files contain function code?
No — only declarations/prototypes; the actual code is in libraries, pulled in by the linker
gcc flag to stop after preprocessing?
gcc -E
gcc flag to stop after compiling (get assembly)?
gcc -S
gcc flag to stop after assembling (get .o, no link)?
gcc -c
Why wrap macro parameters in parentheses?
Macros are dumb text substitution; without parens, operator precedence breaks the intended math
What is relocation (linker)?
Assigning final memory addresses and patching references across merged object files
What's the file trail of the pipeline?
.c → .i → .s → .o → executable

Connections

Concept Map

motivates staging

input to

expands #-directives

translates C to

input to

encodes into

input to

linked into

stitches into

C source hello.c

CPU understands only bytes

Preprocessor cpp

Compiler cc1

Assembler as

Linker ld

Assembly .s

Object file .o

Libraries e.g. printf

Executable binary

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, jab tum gcc hello.c -o hello chalate ho, toh lagta hai ek hi step me kaam ho gaya. Lekin asal me andar 4 tools ek line me kaam karte hain — ek pipeline. Har tool tumhare code ko thoda aur "machine-jaisa" banata hai. Pehle Preprocessor aata hai: yeh #include aur #define jaise # waale lines ko handle karta hai — bilkul copy-paste (text substitution) ki tarah, koi type-checking nahi.

Uske baad Compiler asli kaam karta hai: tumhari C ko samajhta hai, type check karta hai, aur usse assembly language (.s) me badal deta hai jo tumhare CPU ke hisaab se hoti hai. Phir Assembler us assembly ko machine code me convert karke ek object file (.o) banata hai. Yeh .o abhi run nahi hoti, kyunki printf jaise functions ka actual code ismein nahi hota — sirf ek "hole" hota hai jisme likha hai "mujhe printf chahiye".

Aakhri me Linker aata hai — yeh saari .o files aur libraries (jaise libc jisme printf ka code hai) ko jod kar saare holes bharta hai, addresses fix karta hai (relocation), aur ek final executable banata hai jo chal sakti hai. Isiliye undefined reference to 'foo' error linker deta hai, compiler nahi — yeh batata hai ki definition missing hai, syntax galat nahi hai.

Yaad rakhne ka fayda: agar error compiler se aaya toh syntax/type galat hai; agar linker se aaya toh koi function/library missing hai. Aur header files me sirf declarations hoti hain (promise), actual code library me hota hai (delivery) — yeh confusion bahut students ko hoti hai. Pipeline yaad rakho: P-C-A-L, aur files: .c → .i → .s → .o → exe.

Go deeper — visual, from zero

Test yourself — C Programming

Connections