Foundations · #0 of 13

Welcome + the C++ Mental Model

Why C++ in 2026, and what `g++ main.cpp` actually does

Why this course exists

Most C++ tutorials teach you the language Java would have written if Java had no garbage collector. You inherit, you new, you delete, you remember the destructor, you cry into the segfault.

This course teaches the language that wins benchmarks and ships into your phone’s kernel, your browser’s JIT, and the firmware on the satellite reading this page back to you over Starlink. Modern C++ is value-semantics-first. Inheritance hierarchies are de-emphasized. Exceptions are a tool of last resort. The standard library is mostly free functions over generic iterators.

The goal: leave you able to read library code without flinching. Not to memorize the standard.

Why C++ in 2026

Languages overlap, and most of them solve “write a program” perfectly well. C++ is the answer when one of these is non-negotiable:

If none of those is on your critical path, pick a different language and be happier. If even one is — welcome.

How a C++ program becomes a thing that runs

You can write Python by typing into a REPL. You cannot write C++ that way, and the reason is half the curriculum. Every .cpp file you author makes a trip through this pipeline before it executes:

   main.cpp                      ┌──────────────┐
      │                          │  preprocessor│  expands #include,
      ▼                          └──────┬───────┘  resolves #define
   main.i  (the "translation unit")    │
      │                                 ▼
      │                          ┌──────────────┐
      ▼                          │   compiler   │  parses, type-checks,
   main.s  (assembly)            └──────┬───────┘  emits assembly
      │                                 │
      │                                 ▼
      ▼                          ┌──────────────┐
   main.o  (object file)         │   assembler  │  → machine code,
      │                          └──────┬───────┘  with unresolved symbols
      │                                 │
      │   ┌── libstdc++.so ──┐          │
      │   │                  │          ▼
      ▼   ▼                  │   ┌──────────────┐
   ┌──────────────┐          │   │    linker    │  glues object files +
   │   linker     │ ◀────────┘   └──────┬───────┘  libraries, resolves
   └──────┬───────┘                     │           symbol references
          │                             ▼
          ▼                       ./a.out  (runs!)

When you type g++ main.cpp, the compiler driver runs all four stages and throws away the intermediates. You can ask it to stop after any one:

The linker is the part beginners trip over most. When you write std::cout << "hi", the compiler doesn’t contain std::cout. It just records that main.o will need a symbol called std::cout at link time. The linker is what walks the standard-library archive and fills in the blank. A “linker error” is the linker asking: I have this hole, and nothing on the shelf fits it.

The smallest possible program

#include <iostream>

int main() {
std::cout << "hello, " << "world\n";
return 0;
}
idle

Six lines, four pipeline stages, one ABI contract with the OS.

expected output
hello, world
Or run locally
g++ -std=c++23 -O2 snippet.cpp && ./a.out

Read it like a translator:

Six readable lines hide a translation unit of about 30,000 expanded ones, one function the OS recognizes by name, a globally-instantiated stream object, and two operator overloads. Modern C++ is mostly about learning to see all that without it slowing you down.

What “value semantics” means before we go deeper

One sentence preview, because it’s the spine of the whole course:

When you write auto y = x;, you got a copy. Not a reference, not a pointer, not a handle. A whole new x, byte-for-byte. Changing y cannot change x.

This is the opposite of Python (y = x makes y an alias) and the opposite of Java (y = x aliases for objects, copies for primitives). C++ defaults to copy, and the type author decides what “copy” means. That decision — and the machinery around moves, references, and ownership that lets you avoid copies when they’d be wasteful — is the lesson 06 payoff.

Key takeaways

What’s next

Lesson 01 picks up where the hello world ends: what is a std::string, what’s it costing you, and why int x = 5; and int& y = x; are two very different things. Then lesson 03 opens the box on stack vs heap with the memory diagrams this course is going to lean on hard.

If you want to flex first, here’s the project this course builds toward:

Capstone C1 — Custom Allocator. Write a slab allocator that beats new/delete on a real workload. Profile it. Plug it into std::vector via std::pmr. Convince yourself the abstraction really is zero-cost.

That’s the proof of the language. Everything between here and there is runway.