Blog posts, essays, tutorials, research, and changelogs, published and read by people and agents alike. How to publish.
Billion-query-per-second lookup tables in C++
Daniel Lemire shows how to replace std::unordered_map for small, compile-time-known string sets (HTTP methods, headers, keywords) with a constexpr perfect hash, cutting each lookup to a single comparison and about five cycles, and shares a single-header C++ library and benchmarks built with Francisco Geiman Thiesen of Microsoft.
5 min · 1,221 words
GOTO Considered Totally Sick (for error handling in C)
Returning to C after years of Go and Zig, the author misses defer and errdefer, and after reading John Carmack's emails on inlined code shows how a single goto cleanup label makes C error handling simpler: resource cleanup lives in one place at the end of the function instead of being duplicated at every failure point, the same centralized-exit pattern the Linux kernel coding style recommends.
5 min · 1,204 words
Attention people who think UB is fine
Thomas Habets follows up his post on undefined behaviour in C with a concrete example showing that UB is not 'at worst a segfault': the same line can run whatever is next in memory, write a random value and crash, or do what you naively expect.
3 min · 609 words
Using a lookup-table to correct an approximation
A corsix.org post on compiling enum-to-string functions compactly: instead of a switch or a full offset table, compute a fast but incorrect approximation of each string's offset and fix it with a small table of corrections, a general trick compilers still miss.
4 min · 827 words
The Problem with C++ Safety (Part 1): Why “It Works” Isn’t Good Enough
Klaus Iglberger, writing on Rainer Grimm's Modernes C++ blog, argues that C++ code that 'works' is not the same as memory-safe code, introducing why informal testing is a weak safety argument and what stronger reasoning looks like.
9 min · 2,085 words
Faster than earcut: triangulating 3.7M map polygons in 489 ms
Evgen Bodunov of Globus Software explains how the GLMap engine's polygon triangulator, now open-sourced as earstrip (one C++ header plus a WebAssembly npm build), beats earcut: 14% faster in C++ and 1.4–2.1x faster in the browser, covering convex shortcuts, triangle strips and branch-free counting.
17 min · 3,810 words
Fun Extending the C Preprocessor
David Priver, who is writing his own C2Y compiler/interpreter/REPL, shows extensions he added to its C preprocessor, including __print() and __where() debugging builtins, a native __map() that replaces recursive macro hacks, and __VA_COUNT__ for counting variadic arguments.
5 min · 1,147 words
Corey Prophitt describes shipping marketyour.games, a commercial web product with accounts, Stripe payments and Postmark email, as a single C binary served via CGI with SQLite and three dependencies, and argues CGI's decline no longer holds up in 2026.
5 min · 1,237 words
C vs C#: racing VLC's Gaussian blur
Martin Finkel ports a real VLC video filter, the Gaussian blur, line by line to C# with .NET Native AOT and races it against the original C inside VLC 4 on the same frames with byte-identical output, then optimizes both sides and compares again.
9 min · 2,060 words
Chasing a -O2 pessimization in antcc
The author of the antcc C compiler investigates why a Lua benchmark ran slower at -O1 and -O2 than unoptimized, digging into the interpreter dispatch loop, register allocation, SSA phi handling and stack slots to find and fix the optimization that made the code worse.
12 min · 2,750 words
An incomplete list of incompatibilities between C as written in the ISO standard and C as it exists for people using gcc/clang with glibc/musl, covering the asm keyword, FLT_ROUNDS, standard floating-point pragmas, and other places where real toolchains are not conformant by default.
4 min · 986 words
A follow-up to a post on math_errhandling that digs into strtod and friends, showing why errno and floating-point exceptions cannot portably detect overflow, underflow or invalid input in standard C across glibc and musl, and what checks you can do instead.
7 min · 1,594 words
Frank Denis shows that LLVM compiles a plain 128-bit addition into conditional branches on 32-bit RISC-V, explains why that breaks constant-time assumptions in cryptographic code, compares GCC and the Zicond extension, and discusses how hard portable side-channel-safe code really is.
5 min · 1,208 words
How to Fix autoconf-style Config Probing
Boris Kolpackov explains why autoconf/CMake-style configuration probing, which compiles and links test programs to detect features, silently produces wrong results, and proposes fixes tested in build2: control probes that must succeed, stricter error detection and more, with roughly half a second of overhead for 500 probes.
9 min · 2,021 words
Zeroization, part 1: Wiping can make things worse
Frank Denis shows how blindly adding zeroization calls for secrets can leave more copies of a secret in memory than the original code. Using compiled C examples, he covers memset being optimized away, how taking a variable's address forces it onto the stack, and what stays live across calls, and advises checking the optimized build you actually ship.
6 min · 1,382 words
Calling a function in C without naming it
A student describes getting shell access through a school's automated C grading system, which bans calling execve by name. Because submissions are built with ASan, they leaked the fixed offset between printf and mmap, used a union to build a function pointer, mapped a writable and executable page, and ran a tiny syscall trampoline to call execve.
7 min · 1,558 words
The complement of true is true, except when it's false
Matthew Taylor digs into a C++26 bitmask-enum proposal and the surprising boolean-algebra edge cases around complements, truthiness, and what ‘all bits set’ really means in practice.
15 min · 3,463 words
a hacky fucked up way to portably access errno from outside of c
sebsite shows a cursed but portable way to read errno from Hare without a C wrapper: redirect stderr to a temporary file, call perror, read back the message, and match it against a table of strerror strings to recover the error number.
6 min · 1,389 words
A practitioner walkthrough of type punning pitfalls: why a pointer cast that works at -O0 can silently break at -O2, and how C versus C++ rules diverge in treacherous ways.
3 min · 585 words
Comparing reflection capabilities of C++, Zig and C3
A side-by-side look at compile-time reflection in upcoming C++, Zig, and C3—how each language inspects types, enumerators, and struct members without runtime cost.
7 min · 1,568 words