What Actually Happens When You Compile C++ — And Why Interviewers Ask This
Before We Begin
Let me be direct with you.
Most C++ developers — even experienced ones — treat compilation like a black box. You write code, you hit build, something runs. That's it. They never look deeper.
And that is exactly why interviewers ask about it.
When an interviewer asks "what happens when you compile a C++ program?", they are not looking for a one-line answer. They are testing whether you understand the machine beneath your code. They want to know if you are the kind of engineer who knows why things work — not just that they work.
Agar aap yeh lesson seriously lete ho — toh aap pehle din se baaki candidates se alag dikhoge.
Let's go deep.
What The Interviewer Is Actually Testing
When this question comes up in an interview, the interviewer is checking three things simultaneously:
First — Do you understand that compilation is not one step, but a pipeline of four distinct stages? Most candidates say "the compiler converts code to binary." That is like saying "a car converts petrol to motion." Technically true. Completely useless as an answer.
Second — Do you understand what happens at each stage, and more importantly, what can go wrong at each stage? This is where debugging knowledge lives. When you get a linker error vs a compiler error, do you know the difference? Do you know why?
Third — Do you know how this knowledge applies to real decisions? Header files, forward declarations, the ODR rule, why inline exists — these all make sense only when you understand compilation. Senior engineers are expected to connect theory to practice.
Yeh question ek gateway hai — agar aap iska jawab confidently dete ho, interviewer automatically assume karta hai ki aap baaki concepts bhi deeply samajhte ho.
The Four Stages of C++ Compilation
C++ compilation is a pipeline. Your source code goes through four distinct stages before it becomes an executable that runs on your machine. Each stage has a specific job, specific inputs, and specific outputs.
Now let us understand each stage properly. Not surface level — properly.
Stage 1 — The Preprocessor
The preprocessor runs before the C++ compiler even sees your code. It knows nothing about C++. It is a pure text manipulation tool.
Its job is simple: take your .cpp file and produce an expanded .i file by processing all the directives that start with #.
Think of it like this — preprocessor ek copy-paste machine hai. Koi intelligence nahi, sirf text replacement.
What it does:
#include — File Inclusion
When you write #include <iostream>, the preprocessor literally copies the entire content of iostream and pastes it where your #include line was. That is it. No magic. Just copy-paste.
This is why when you include a heavy header file, your compilation slows down — the preprocessor is pasting thousands of lines of code into your file before compilation even begins.
#define — Macro Substitution
Notice the extra parentheses in SQUARE(x). This is intentional — aur yeh ek common interview gotcha hai. Hum aage dekhenge kyun.
#ifdef, #ifndef, #endif — Conditional Compilation
Yeh hai header guard — aur yeh isliye exist karta hai kyunki agar same header do jagah include ho jaaye, toh preprocessor usse do baar paste kar deta. Header guard ensure karta hai ki content sirf ek baar paste ho.
You can see the preprocessor output yourself:
Open your_file.i and you will see everything your preprocessor produced. Hazaron lines of code — sirf ek #include <iostream> se.
Stage 2 — The Compiler
Now the real work begins. The compiler takes the preprocessor output (.i file) and converts it to assembly language (.s file).
This stage has three sub-stages internally:
Important: Each .cpp file is compiled independently. The compiler does not know about your other .cpp files. It only sees one translation unit at a time.
Yeh ek critical concept hai — translation unit. Ek .cpp file + uske saare included headers = ek translation unit. Compiler ek time pe sirf ek translation unit dekhta hai.
This is why you can declare a function in a header, define it in one .cpp file, and use it in another .cpp file — the compiler trusts your declaration and moves on. It is the linker's job to connect everything later.
Compiler errors happen here. Type mismatches, undeclared variables, syntax errors — sab yahan pakde jaate hain.
You can see the assembly output yourself:
Stage 3 — The Assembler
The assembler takes assembly code (.s) and converts it to machine code — actual binary instructions your CPU understands. The output is an object file (.o or .obj).
The object file contains:
- Machine code for all the functions you defined
- A symbol table — a list of all the names (functions, variables) this file defines and all the names it needs from elsewhere
The "UNDEFINED" symbols are essentially IOUs — "main.o ko add() function chahiye, koi dega?"
The linker collects all these IOUs and resolves them.
Stage 4 — The Linker
The linker is where everything comes together. It takes all your .o files — plus any library files you are using — and combines them into a single executable.
The linker's primary job: resolve all undefined symbols.
Linker errors happen here. When you see "undefined reference to foo()" — that is the linker telling you it could not find who defines foo().
This is different from a compiler error. Samjho:
- Compiler error = aapka ek sentence grammatically galat hai
- Linker error = aapne kisi ka naam liya jo exist hi nahi karta
Stage 5 — The Loader (Runtime)
The loader is not part of compilation — it runs at runtime, when you execute your program.
The operating system's loader:
- Reads your executable file
- Allocates memory for it
- Copies the program into memory
- Sets up the stack and heap
- Jumps to the
main()function
Yeh memory layout samajhna bohot zaroori hai — Stack vs Heap wala lesson isi ke upar build hoga.
The Gotcha Section — "Yeh Mat Bolna Interview Mein"
Mistake #1 — Ek stage ka answer dena
❌ "Compiler C++ code ko binary mein convert karta hai."
Yeh sunke interviewer andar se soch raha hota hai — "isko sirf compiler pata hai, baki kuch nahi."
✅ "C++ compilation is a four-stage pipeline — preprocessing, compilation, assembly, and linking. Each stage has a distinct job..."
Mistake #2 — Linker error aur compiler error ko confuse karna
Bahut log bolte hain "compiler ne error diya" jab actually linker ne error diya. Yeh ek sign hai ki candidate compilation pipeline nahi samjha.
✅ Jab bhi error aaye — pehlo dekho ki woh error message
ld:se start hota hai yagcc:/clang:se.ld= linker. Isi se pata chalta hai kahan gadbad hai.
Mistake #3 — #include ko "import" bolna
Java aur Python mein import hota hai. C++ mein #include sirf copy-paste hai. Yeh ek significant difference hai — import smart hai, #include dumb hai. Interviewers yeh distinction jaante hain.
How To Answer In The Interview — Word For Word
Interviewer: "What happens when you compile a C++ program?"
You say:
"C++ compilation is a four-stage pipeline. First, the preprocessor runs — it handles all
#includedirectives by literally copying header content, expands macros, and processes conditional compilation. It produces an expanded source file.Second, the compiler takes that expanded source and converts it to assembly language. This is where type checking, syntax validation, and optimizations happen. Each
.cppfile is compiled independently as a translation unit.Third, the assembler converts assembly to machine code, producing object files. Each object file contains a symbol table — a list of what it defines and what it needs from elsewhere.
Fourth, the linker takes all object files and resolves the undefined symbols by matching them across files and libraries. This is where 'undefined reference' errors come from.
At runtime, the OS loader maps the executable into memory, sets up the stack and heap, and transfers control to
main()."
Pause. Let the interviewer respond. Do not rush.
Follow-Up Questions The Interviewer Will Ask
Q: "What is a translation unit?"
A translation unit is a single
.cppfile after preprocessing — including all the headers it pulled in. The compiler processes one translation unit at a time, independently.
Q: "What is the ODR rule?"
The One Definition Rule states that any function or variable can be declared multiple times but defined only once across all translation units. Violating ODR causes linker errors — or worse, undefined behavior.
Q: "Why do we put declarations in header files and definitions in .cpp files?"
Because headers get included in multiple translation units. If you put a definition in a header, it gets defined multiple times — violating ODR and causing linker errors. Declarations are safe to repeat; definitions are not.
Q: "What is the difference between a compiler error and a linker error?"
Compiler error — something wrong within a single translation unit. Type mismatch, undeclared name, syntax error. Linker error — the symbol exists in the declaration but the definition was never found across all object files.
Q: "What does static do at file scope?"
It gives the symbol internal linkage — meaning the linker will not export it to other translation units. It is invisible outside its own
.cppfile. This is how you create file-private functions in C++.
Quick Revision — Raat Ko Interview Se Pehle Padho
Mind Map — How This Lesson Connects To The Rest Of The Course
Practice Problems
Easy — Identify The Stage
Look at each error below. Which compilation stage produced it?
Answers: Error 1 = Linker. Error 2 = Compiler. Error 3 = Loader/Runtime — undefined behavior.
Medium — Spot The ODR Violation
Question: What goes wrong here and at which stage?
Answer: ODR violation. add() gets defined twice — once per translation unit that includes utils.h. The linker sees two definitions and throws a "multiple definition" error. Fix: put only the declaration in the header, move the definition to a .cpp file. Or mark it inline.
Hard — Design Question
Question: You are building a large C++ codebase. A junior engineer has put all function definitions in header files — claiming "it's simpler since everything is in one place." What problems will this cause, and how do you fix it?
Write a detailed answer covering: ODR violations, compilation time impact, when it is actually acceptable (hint: inline, template), and what the correct approach is.
Further Reading
- Run
g++ -v your_file.cppto see every stage GCC runs internally - Read "Linkers and Loaders" by John Levine — the definitive book on this topic
- cppreference: Translation Units
- Next Lesson → Stack vs Heap: Answer This Wrong and You Fail the Interview
— CPPValley | Core C++ for Interviews | Module 1, Lesson 1