latency.lab
Module 00

Toolchain & First Program

Level: beginnerTime: ~45 minPrereq: none

By the end you can

Before you write a single interesting line of C++, you need to understand what happens when you press "run." Most beginners treat the build as magic. At a trading firm, the build is the job half the time. So we start here.

What C++ actually is

C++ is a compiled language. Unlike Python or JavaScript, your source code is never run directly. Instead a program called the compiler translates your human-readable .cpp files into machine code the CPU executes directly. This is why C++ is fast: there is no interpreter sitting between your code and the processor at runtime.

The translation happens in stages, and knowing them will save you hours of confusion later:

  1. Preprocessing — handles lines starting with #. #include literally pastes the contents of another file into yours.
  2. Compilation — turns each .cpp file into an object file (.o) full of machine code. Each file is compiled independently.
  3. Linking — stitches all the object files (and libraries) together into one executable. If you call a function that exists but never got linked, this is the stage that fails.
Remember this

"Compiler error" and "linker error" are different animals. A compiler error means your code is malformed in one file. A linker error (often "undefined reference to...") means the code is fine but the definition of something couldn't be found at link time. Beginners waste hours because they don't know which stage failed.

Installing the toolchain

You need two things: a compiler (g++ or clang++) and cmake.

macOS

terminal
# installs clang++, the Apple compiler
xcode-select --install
# install cmake via Homebrew
brew install cmake

Linux (Debian / Ubuntu)

terminal
sudo apt update
sudo apt install build-essential cmake

Windows

Easiest path is WSL2 (Windows Subsystem for Linux), then follow the Linux steps inside it. This is also closest to the Linux environment trading firms actually deploy on, so it's worth doing. Alternatively, install MSYS2 or use Visual Studio's C++ workload.

Verify everything works:

terminal
g++ --version      # or: clang++ --version
cmake --version

Your first program

Create a file called hello.cpp:

hello.cpp
#include <iostream>

int main() {
    std::cout << "Hello, Latency Lab\n";
    return 0;
}

Line by line, because every piece matters:

  • #include <iostream> pulls in the input/output stream library so you can print to the console.
  • int main() is the entry point. Every C++ program starts executing here. It returns an int to the operating system.
  • std::cout is the standard output stream. The << operator sends data to it.
  • "\n" is a newline. std:: is the namespace the standard library lives in — more on that soon.
  • return 0; tells the OS the program succeeded. Non-zero means failure. This convention matters when your program is one stage in a pipeline.

Compile and run it directly

terminal
g++ -std=c++17 -Wall -Wextra hello.cpp -o hello
./hello

What those flags mean:

  • -std=c++17 — use the C++17 standard. Always specify this. Defaults vary by compiler.
  • -Wall -Wextra — turn on warnings. Always compile with warnings on. They catch real bugs before they run. At a trading firm, warnings are often treated as errors.
  • -o hello — name the output executable hello. Without it you get a.out.
Habit to build now

Add -Wall -Wextra -Wpedantic to every compile from day one. The single fastest way to become a better C++ programmer is to read and fix every warning instead of ignoring it.

Building with CMake

Compiling one file by hand is fine. Real projects have dozens. CMake is the build system that manages this — it's what nearly every C++ shop uses, including the order book you'll build in Module 12.

Create CMakeLists.txt next to hello.cpp:

CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(hello LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(hello hello.cpp)

Every line explained:

  • cmake_minimum_required — the oldest CMake version that can build this. Prevents cryptic failures.
  • project(...) — names the project and declares it uses C++ (CXX).
  • CMAKE_CXX_STANDARD 17 — enforce C++17 without you passing -std by hand.
  • add_executable — build an executable named hello from hello.cpp.

Build it the standard "out-of-source" way (keeps generated files out of your source folder):

terminal
cmake -S . -B build      # configure: read CMakeLists, generate build files into build/
cmake --build build      # actually compile
./build/hello            # run
Build

Exercise 00.1 — Make it yours

Get the toolchain working and prove it to yourself:

  • Install the compiler and CMake. Run the two --version commands successfully.
  • Compile hello.cpp both ways: directly with g++, and via CMake.
  • Modify the program to also print your name and today's date on separate lines.
  • Deliberately break it: delete a semicolon and recompile. Read the error. Then delete the #include and recompile. Notice how the errors differ. This is how you learn to read compiler output.

Takeaways

  • C++ is compiled: source → object files → linked executable. Three stages, three kinds of failure.
  • Compiler errors are per-file and syntactic. Linker errors ("undefined reference") mean a definition was missing at link time.
  • Always compile with -std=c++17 -Wall -Wextra. Warnings are free bug reports.
  • int main() is the entry point and returns 0 on success.
  • CMake manages real builds. cmake -S . -B build then cmake --build build.

Checkpoint · Toolchain

5 questions · pass at 70%

Q01
Which build stage produces the "undefined reference to ..." error?
WhyThe linker stitches object files together. If a declared function has no definition anywhere at link time, the linker reports an undefined reference. The code compiled fine — it just couldn't be assembled into a whole program.
Q02
What does #include <iostream> do during preprocessing?
Why#include is a text operation handled by the preprocessor. It literally inserts the header's contents at that point in your file before compilation begins.
Q03
Why should you always pass -std=c++17 explicitly?
WhyDifferent compilers and versions default to different language standards. Being explicit guarantees everyone builds your code against the same standard.
Q04
What does main returning a non-zero value signal to the operating system?
WhyBy convention 0 means success and any non-zero value signals failure. This matters when your program is one stage in a shell pipeline or automated system.
Q05
Why compile with -Wall -Wextra?
WhyThese flags enable warnings that frequently surface genuine bugs (uninitialized variables, unused results, sign mismatches). Reading and fixing them is one of the fastest ways to improve.

Finished Module 00?

Passing the quiz marks it complete automatically. Or mark it yourself.

+ Note