latency.lab
Module 01

Fundamentals

Level: beginnerTime: ~90 minPrereq: Module 00

By the end you can

Fundamental types

C++ gives you a small set of built-in types. Unlike Python where an integer is an object, these map directly to hardware. That's the source of both C++'s speed and its footguns.

types.cpp
int      i  = 42;        // usually 32-bit signed integer
long     l  = 42L;       // at least 32-bit, often 64
long long ll = 42LL;    // at least 64-bit
double   d  = 3.14;      // 64-bit floating point
float    f  = 3.14f;     // 32-bit floating point
char     c  = 'A';       // 1 byte, holds a character code
bool     b  = true;      // true or false

The exact size of int and long is not fixed by the standard — only minimums are guaranteed. When you need exact widths (and in systems code you often do), use the fixed-width types from <cstdint>:

fixed.cpp
#include <cstdint>
int32_t  price_ticks = 15025;   // exactly 32 bits, signed
uint64_t order_id    = 1;       // exactly 64 bits, unsigned
Why this matters at a trading firm

Order IDs, timestamps, and prices all have exact width requirements dictated by exchange protocols. Using int where the protocol says 64-bit unsigned is a real bug. This is why the order book in Module 12 uses uint64_t for IDs and int64_t for prices.

Integer overflow

Integers have a fixed range. Exceed it and behavior is either wraparound (unsigned) or undefined (signed). Undefined behavior is the villain of this entire course — remember the word.

overflow.cpp
int32_t big = 2147483647;   // max value of a signed 32-bit int
big = big + 1;               // signed overflow: UNDEFINED behavior

uint32_t u = 0;
u = u - 1;                     // unsigned wraps to 4294967295 (defined, but a trap)

The unsigned wraparound bites constantly in loops like for (size_t i = n-1; i >= 0; --i) — because an unsigned value is never less than zero, that loop never ends.

Floating point is not exact

double cannot represent most decimal fractions precisely. 0.1 + 0.2 is not exactly 0.3.

float.cpp
if (0.1 + 0.2 == 0.3) { /* NEVER runs — the sum is 0.30000000000000004 */ }
The money rule

Never store money as double. Represent prices as integers in the smallest unit (cents, or ticks). $150.25 becomes the integer 15025. This eliminates rounding bugs and comparison failures. It's exactly what real exchanges do and what your order book will do.

Control flow

control.cpp
if (price > best_bid) {
    // ...
} else if (price == best_bid) {
    // ...
} else {
    // ...
}

for (int i = 0; i < 10; ++i) { /* classic loop */ }

while (order.remaining() > 0) { /* runs until condition false */ }

// range-based for: iterate a container directly (C++11+)
for (const auto& trade : trades) {
    // read each element by reference, no copy
}

Prefer ++i over i++ in loops. For integers it doesn't matter, but for iterators (Module 08) the pre-increment can avoid a copy. Building the habit now pays off later.

Functions and scope

functions.cpp
// pass by value: 'x' is a COPY. Changes don't affect the caller.
int square(int x) { return x * x; }

// pass by reference: 'x' is the SAME object. Changes affect the caller.
void double_it(int& x) { x *= 2; }

// pass by const reference: no copy, and cannot modify. Ideal for big objects.
void print(const std::string& s) { std::cout << s; }

This distinction is central to C++ and we'll go much deeper in Module 03. The one-line summary: pass small things by value, big things by const reference.

Scope is the region where a name is valid. A variable declared inside { } ceases to exist when that block ends — and if it owned a resource, that resource is released. This is the seed of RAII (Module 04), the most important idea in C++.

Build

Exercise 01.1 — Tick math

Write a small program that works entirely in integer price ticks:

  • Store two prices as int64_t in cents (e.g. 15025 for $150.25).
  • Write a function int64_t spread(int64_t bid, int64_t ask) returning the difference.
  • Write a function that formats a tick price back into a dollar string like "$150.25".
  • Prove to yourself that 0.1 + 0.2 == 0.3 is false by printing the sum with std::cout.precision(20).

Takeaways

  • Fundamental types map to hardware. Use <cstdint> fixed-width types when width matters.
  • Signed overflow is undefined behavior; unsigned wraps around. Both cause real bugs.
  • Never use double for money. Use integer ticks.
  • Pass small things by value, large things by const reference.
  • Scope controls lifetime. When a block ends, its local objects are destroyed — the foundation of RAII.
Live

Loading starter code…

Checkpoint · Fundamentals

6 questions · pass at 70%

Q01
What happens when a signed 32-bit int at its maximum value is incremented by 1?
WhySigned integer overflow is undefined behavior in C++. Unsigned overflow, by contrast, is well-defined wraparound. Never rely on signed overflow.
Q02
Why should money be stored as an integer number of ticks rather than a double?
WhyFloating point represents values in binary and cannot exactly hold most decimals (0.1, 0.2, etc.). Integer ticks are exact, which is why exchanges and your order book use them.
Q03
This loop: for (size_t i = n-1; i >= 0; --i) with n > 0 will...
Whysize_t is unsigned, so i >= 0 is always true. When i is 0 and decremented, it wraps to a huge positive number. Classic unsigned bug.
Q04
You need to pass a large std::string into a function without copying it, and you won't modify it. What is the right parameter type?
Whyconst std::string& passes by reference (no copy) and forbids modification. This is the standard way to pass large read-only objects.
Q05
When does a local variable declared inside a { } block get destroyed?
WhyAutomatic (stack) objects are destroyed when execution leaves their scope. C++ has no garbage collector; deterministic destruction at scope exit is what enables RAII.
Q06
What is the difference between int and int32_t?
WhyThe standard only guarantees minimum sizes for int/long. int32_t (from ) is exactly 32 bits, which you need when matching exact protocol layouts.

Finished Module 01?

Pass the quiz to complete it automatically.

+ Note