Chapter 07 of 30
Preprocessor, Debug Macros & Compilation
Understand the C++ preprocessor, essential debug macros, and compilation flags for competitive programming.
The C++ Preprocessor & MacrosCompilation Pipeline & G++ Compiler Flags
Share:
Preprocessor, Debug Macros & Compilation
The preprocessor runs before compilation, transforming your source code. Understanding it helps you write shorter contest code and debug faster.
The C++ Preprocessor & Macros
What is a Macro?
A macro is a text substitution that happens before compilation:
hljs cpp
#define ll long long
#define vi vector<int>
#define pii pair<int,int>
ll n; // becomes: long long n;
vi a; // becomes: vector<int> a;
pii p; // becomes: pair<int,int> p;
Macros with Parameters
hljs cpp
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
sort(all(a)); // sort(a.begin(), a.end())
int n = sz(a); // int n = (int)(a).size();
Macros vs Inline Functions
| Feature | Macro | Inline Function |
|---|---|---|
| Type safety | No | Yes |
| Debuggable | Harder | Yes |
| Speed | Same (text substitution) | Same |
| Debug macros | Yes | No |
For competitive programming, macros are fine for type aliases and shorthand. For anything with logic, prefer inline functions.
Preprocessor Directives
hljs cpp
#include <bits/stdc++.h> // include entire standard library
#define MOD 1000000007 // text replacement
#undef MOD // undo a #define
#ifdef DEBUG // conditional compilation
cerr << "debug: " << x << "\n";
#endif
#ifndef ONLINE_JUDGE // if not on a judge
freopen("input.txt", "r", stdin);
#endif
Include Guards
Header files use include guards (or #pragma once) to prevent double inclusion:
hljs cpp
#pragma once
// header content here
Compilation Pipeline & G++ Compiler Flags
Compilation Steps
- Preprocessing:
#include,#define,#ifdefare resolved - Compilation: C++ code → assembly
- Assembly: assembly → object file (
.o) - Linking: object files → executable
Essential Flags
hljs bash
g++ -O2 -std=c++17 -Wall -Wextra -o solution solution.cpp
| Flag | Purpose |
|---|---|
-O2 | Optimization level 2 (always use in contests) |
-std=c++17 | C++17 standard |
-Wall | Enable all common warnings |
-Wextra | Enable additional warnings |
-o name | Output executable name |
-g | Include debug symbols (for gdb) |
-fsanitize=address | Memory error detector (for debugging) |
-DLOCAL | Define a macro (for debug builds) |
Debug Build
hljs bash
# Debug: no optimization, debug symbols, sanitizers
g++ -O0 -std=c++17 -g -fsanitize=address,undefined -DLOCAL -o debug solution.cpp
# Contest: optimized
g++ -O2 -std=c++17 -o solution solution.cpp
Fast I/O and O2
Always compile with -O2 in contests. Judges use it, so your solution's time complexity assumes optimized code. Without -O2, even correct solutions may TLE.
Summary
- Macros are text substitution — use for type aliases (
#define ll long long) and shorthand #definehas no type safety; preferusingfor type aliases when possible- Always compile with
-O2in contests - Use
-fsanitize=address,undefinedduring development to catch bugs #ifndef ONLINE_JUDGElets you usefreopenfor local testing without affecting judge submissions
Prefer reading offline? Download the full book as a PDF.
Download Free Book