02 — Compilers and Toolchains

You install both gcc and clang, and you build against both regularly. Not because you’re indecisive, but because catching bugs is a numbers game: gcc’s warnings sometimes catch what clang’s don’t, and vice versa. -fsanitize= on clang is often ahead of gcc’s implementation. Cross-compiler discipline is what separates hobbyist C from professional C.

GCC 15 (mid-2026 stable)

Current stable: GCC 15.2 (released Aug 8 2025). GCC 15.1 released April/May 2025. GCC 16 is under development; do not chase it.

What’s new that affects you:

  • Default C standard is now gnu23. If you want strict portable C, pass -std=c17 or -std=c23 explicitly.

  • Full C23 language support including _BitInt, #embed, improved typeof, constexpr at file scope.

  • AVX10.2 codegen (relevant for Intel Xeon deployments).

  • Improved OpenMP 6.0 support.

  • Incremental LTO — much less painful -flto builds.

  • COBOL front-end (gcobol) — irrelevant to you; skip.

Install:

  • macOS: brew install gcc — installs as gcc-15 (not gcc).

  • Ubuntu 26.04: sudo apt install gcc g++ — GCC 15 is default.

  • WSL2 Ubuntu 26.04: same.

Verify: gcc-15 --version (Mac) or gcc --version (Linux) → shows 15.2.0 or newer.

Clang / LLVM 20 (mid-2026 stable)

Current stable: LLVM/Clang 20.1 (first stable of the 20 series, released March 2025). Clang 21 discussed at Oct 2025 LLVM devmtg; expect it late 2025/early 2026 — use if you like, 20.1 is fine.

Why you also want clang:

  • Sanitizer implementations often lead gcc’s.

  • Better error messages (still).

  • clang-tidy, clang-format, scan-build are part of the same toolchain.

  • clangd (see file 03) is the LSP for C.

Install:

  • macOS: xcode-select --install (bundled clang). For latest, brew install llvm and put /opt/homebrew/opt/llvm/bin on PATH.

  • Ubuntu: sudo apt install clang lldb clang-tools clang-tidy clang-format clangd.

Verify: clang --version.

The two-compiler discipline

Always build once with each in CI (even in your personal projects). Simple pattern in a Makefile:

CC ?= gcc
CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -O2 -g

all: prog

prog: main.c
	$(CC) $(CFLAGS) -o $@ $<

check:
	CC=gcc $(MAKE) prog
	CC=clang $(MAKE) prog
	./prog
	CC=clang CFLAGS="$(CFLAGS) -fsanitize=address,undefined" $(MAKE) prog
	./prog

ccache — install unconditionally

What: compiler cache; hashes preprocessed source, caches object files. Makes rebuilds 5-20x faster.

Install: brew install ccache / apt install ccache.

Setup: add to ~/.zshrc or ~/.bashrc:

export PATH="/opt/homebrew/opt/ccache/libexec:$PATH"   # Mac
export PATH="/usr/lib/ccache:$PATH"                    # Ubuntu
export CCACHE_DIR="$HOME/.ccache"
export CCACHE_MAXSIZE="5G"

Verify: ccache -s shows stats after your next build.

Linkers — mold vs default ld/lld/gold

mold (rui314/mold, https://github.com/rui314/mold) is a modern parallel linker written by the same author as lld and gold. In benchmarks it is 5-25x faster than lld/gold for large C/C++ links.

Linker

Platform

Notes

mold

Linux (primary), FreeBSD, macOS (sold, alpha)

Best choice on Linux

lld

All

LLVM’s linker, second-best

gold

Linux

Being deprecated

BFD ld (default ld)

All

Slowest, most portable

ld64 (Apple)

macOS

The macOS system linker; still the right default on Mac. sold (mold’s Mac fork) exists but is not ready for daily use.

Install mold on Ubuntu 26.04: sudo apt install mold.

Use with GCC 12.1+ or Clang:

gcc -fuse-ld=mold -o prog main.c

Verify: mold --version. Measure your before/after link time on a real project.

Which compiler for what

  • Learning / canonical builds: gcc 15 with -std=c17 -Wall -Wextra -Wpedantic -O2 -g.

  • Sanitizer runs: clang 20 with -fsanitize=address,undefined,integer (clang’s sanitizer set is broader than gcc’s).

  • Comparing codegen: godbolt.org (Compiler Explorer) with both, side by side.

  • CI: both, always. If your code compiles cleanly on both with -Werror, you have caught most portability bugs.

What most people get wrong about compilers

They install one, forget about it, and don’t turn on warnings. Then they wonder why they have subtle bugs. Minimum warning flags for every project, day one:

-Wall -Wextra -Wpedantic -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wconversion -Wdouble-promotion -Werror

Start there. Add -Wanalyzer-* on gcc for the static analyzer, -fsanitize=address,undefined for runtime.

Return to README.md · Next: 03_editor_and_lsp.md