C++ Code : Converted to Machine
A Step-by-Step Guide (GCC)

I am an Information Science student, primarily focused on developing projects. Writing blogs is one of my hobbies, though I do not publish them very frequently.
C++ is a powerful, high-performance language—but have you ever wondered how your C++ code becomes an executable file your computer can run?
In this blog, we’ll explore how C++ code gets converted into machine code, and how to generate each intermediate file yourself using g++. By the end, you'll have a solid understanding of how your human-readable code ends up as binary instructions executed by a CPU.
🚦 Overview of the Conversion Flow
Here's the general flow from source code to executable:
C++ Code (.cpp)
↓
Preprocessing (.i)
↓
Compilation to Assembly (.s)
↓
Assembly to Object Code (.o)
↓
Linking to Executable (no extension or .exe)
↓
Execution by CPU (Machine Code)
Let’s break each part down.
1️⃣ Writing the Source Code (.cpp)
Create a file named source.cpp:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
This is human-readable code written in C++.
2️⃣ Preprocessing (.i file)
The preprocessor handles directives like #include, #define, and macro expansions.
Run this command:
g++ -E source.cpp -o source.i
🔍 What Happens:
#include <iostream>is replaced with the full contents of the iostream header file.Macros are expanded.
Comments are removed.
Output is saved to
source.i.
Open source.i to see what the compiler will work on next.
3️⃣ Compilation to Assembly (.s file)
Next, compile the preprocessed code into assembly language.
g++ -S source.cpp -o source.s
🔍 What Happens:
Your C++ code is converted to architecture-specific assembly instructions (e.g., x86 or ARM).
Output is saved in
source.s.
This file is still human-readable but much closer to machine code.
4️⃣ Assembling to Object File (.o file)
Now convert the assembly code into machine code, but not yet executable.
g++ -c source.cpp -o source.o
🔍 What Happens:
The assembler converts assembly to machine-level binary.
Output:
source.o— contains machine code but is not yet executable.
You can’t run this file directly—it still needs linking.
5️⃣ Linking to Executable
This step links your object file with C++ libraries (like the Standard Library).
g++ source.o -o program
🔍 What Happens:
The linker resolves all external symbols and references (like
std::cout).Combines your object file with library code into a final executable.
Output: program — the complete, runnable file!
6️⃣ Running the Executable
Just run:
./program
You should see:
Hello, world!
🧠 Bonus: Viewing Machine Code
Want to see actual machine instructions?
Use objdump to disassemble the binary:
objdump -d program
This will show assembly-like output of the machine code that the CPU will execute.
🧾 Summary Table
| Stage | Command | Output File | Description |
| Preprocessing | g++ -E source.cpp -o source.i | source.i | Expanded C++ source code |
| Compilation | g++ -S source.cpp -o source.s | source.s | Assembly code |
| Assembling | g++ -c source.cpp -o source.o | source.o | Machine code (object file) |
| Linking | g++ source.o -o program | program | Final executable file |
| Execution | ./program | — | Runs the machine code |
| Disassembly | objdump -d program | — | Shows disassembled machine instructions |
🧰 Automating the Full Flow
Here’s a simple shell script to automate all steps:
#!/bin/bash
g++ -E source.cpp -o source.i
g++ -S source.cpp -o source.s
g++ -c source.cpp -o source.o
g++ source.o -o program
echo "Compiled and linked successfully. Run with ./program"
Save as build.sh, make it executable with:
chmod +x build.sh
And run:
./build.sh
👨🔧 Final Thoughts
Understanding how C++ code is transformed into machine code is essential for anyone who wants to master systems programming, compiler design, or even just become a more confident developer.
Hopefully, this gave you a clear picture of each step in the compilation toolchain!
💬 If you enjoyed this post or have questions, drop a comment below!

