Docs

compilation process

šŸ”§ The C++ Compilation Process

Overview

Unlike interpreted languages (Python, JavaScript), C++ is a compiled language. Your source code must be transformed into machine code before it can run.

The Four Stages of Compilation

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  Source Code    │  (.cpp, .h files)
│   main.cpp      │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
         │ STAGE 1: Preprocessing
         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  Preprocessed   │  (Expanded code)
│    Code         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
         │ STAGE 2: Compilation
         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  Assembly Code  │  (.s file)
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
         │ STAGE 3: Assembly
         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  Object Code    │  (.o file)
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
         │ STAGE 4: Linking
         ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│   Executable    │  (Binary)
│   ./program     │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Stage 1: Preprocessing

The preprocessor handles directives starting with #:

// Before preprocessing
#include <iostream>
#define PI 3.14159
#define SQUARE(x) ((x) * (x))

int main() {
    double area = PI * SQUARE(5);
    return 0;
}

// After preprocessing
// (iostream contents expanded here - thousands of lines)

int main() {
    double area = 3.14159 * ((5) * (5));
    return 0;
}

Preprocessor Tasks:

  • •#include - Insert contents of header files
  • •#define - Replace macros with their values
  • •#ifdef/#ifndef - Conditional compilation
  • •#pragma - Compiler-specific instructions
  • •Remove comments

See Preprocessed Output:

g++ -E main.cpp -o main.i

Stage 2: Compilation

The compiler translates preprocessed code into assembly language:

; Assembly output (simplified)
main:
    push    rbp
    mov     rbp, rsp
    movsd   xmm0, QWORD PTR .LC0[rip]
    movsd   QWORD PTR [rbp-8], xmm0
    mov     eax, 0
    pop     rbp
    ret
.LC0:
    .long   1374389535
    .long   1075388088

What Happens:

  • •Syntax checking
  • •Type checking
  • •Optimization (if enabled)
  • •Generate assembly code

See Assembly Output:

g++ -S main.cpp -o main.s

Stage 3: Assembly

The assembler converts assembly code into machine code (object file):

Object file contains:
- Machine code (binary)
- Symbol table (function/variable names)
- Relocation information

Generate Object File:

g++ -c main.cpp -o main.o

Stage 4: Linking

The linker combines object files and libraries into the final executable:

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”     ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│   main.o     │     │   utils.o    │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜     ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
       │                    │
       ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                │
        ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
        │    LINKER     │
        ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                │
       ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
       │                 │
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā”€ā”   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  C++ Std    │   │   System    │
│  Library    │   │  Libraries  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                │
        ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā–¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
        │  Executable   │
        │   ./program   │
        ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Linker Tasks:

  • •Resolve external references
  • •Combine object files
  • •Link standard library functions
  • •Create final executable

Complete Compilation Commands

# All-in-one (most common)
g++ main.cpp -o program

# Step by step
g++ -E main.cpp -o main.i      # Preprocess
g++ -S main.i -o main.s        # Compile to assembly
g++ -c main.s -o main.o        # Assemble to object
g++ main.o -o program          # Link to executable

# With multiple files
g++ file1.cpp file2.cpp file3.cpp -o program

# With options
g++ -std=c++17 -Wall -Wextra -O2 main.cpp -o program

Compiler Flags Explained

FlagPurpose
-std=c++17Use C++17 standard
-WallEnable common warnings
-WextraEnable extra warnings
-WerrorTreat warnings as errors
-O0No optimization (debug)
-O2Moderate optimization
-O3Aggressive optimization
-gInclude debug symbols
-cCompile only (no linking)
-o nameSpecify output filename

Common Compilation Errors

1. Syntax Error (Compilation Stage)

int main() {
    cout << "Hello"  // Missing semicolon
    return 0;
}
error: expected ';' before 'return'

2. Undefined Reference (Linking Stage)

void myFunction();  // Declared but never defined

int main() {
    myFunction();   // Linker can't find it
    return 0;
}
undefined reference to 'myFunction()'

3. Multiple Definition (Linking Stage)

// file1.cpp
int global = 5;

// file2.cpp
int global = 10;  // Same name!
multiple definition of 'global'

Practical Exercise

Create a simple program and observe the compilation stages:

// hello.cpp
#include <iostream>

int main() {
    std::cout << "Hello, C++ World!" << std::endl;
    return 0;
}
# Try each stage
g++ -E hello.cpp > hello.i     # Look at preprocessed output
g++ -S hello.cpp               # Creates hello.s (assembly)
g++ -c hello.cpp               # Creates hello.o (object)
g++ hello.o -o hello           # Creates executable
./hello                        # Run it!

Next: Your First C++ Program

Compilation Process - C++ Tutorial | DeepML