Keynote Speakers

Refraction: One File In, a Spectrum Out
I keep writing the same emulators over and over again. Not because I have to (though I enjoy it more than I should) but because every time I finish one I can see a better way it could have been done. Every one of those better ways has ended in the same place: either some awkward template metaprogramming or a program that writes a program, run by the build system.
I don’t think it’s just me. Every serious way of describing an instruction set works this way, and has for thirty years: code generation is simply how it’s done. So I have been trying to throw my code generator away and replace it with a single file describing a CPU, read and understood while the program is being compiled, and see how much of what I used to generate the language can now derive for itself.
This is a report from that attempt: what it cost, what broke, some classic games, and hopefully a working emulator.

The Theory of Your Code
In 1980, Meir Lehman wrote that “any program is a model of a model within a theory of a model of an abstraction of some portion of the world or of some universe of discourse.”
In 1985, Peter Naur conceived of programming as theory building. By this he meant that developing software is more than the creation of code: software development involves the creation of a collective understanding, a shared model, a theory of a software system. While the code may well tell the truth, it is far from the whole truth. Systems become legacy when the theory of a system is lost or fractured — intent is obscured, changes are at odds with the system concept, the architecture and its qualities are neglected. This degradation can come from staff turnover, technical neglect and unconditional acceptance of generated code.
In 2026, we’ll use this perspective to understand how we try — and fail — to create, communicate and maintain the model of code, from naming conventions to paradigms, from types and contracts to tests and specifications, from patterns to ADRs. Given the shearing forces of markets, software development organisations, AI and more, we need to figure out how we make theory practical.

What the C++ Committee Taught Me About Building Extensibility into Claude Code
A year and a half ago I left almost a decade on the ISO C++ committee to join Anthropic. I ended up joining a small team working on an agentic coding tool. That tool became Claude Code, and somewhere along the way I noticed I was reaching for my C++ committee instincts more often than I expected.
Some of them are principles every C++ programmer already carries. “Don’t pay for what you don’t use” reads differently when the fixed-size target is a context window that isn’t growing the way everything around it is, and every extension point you add is resident on every request. Others, like the orthogonality of customization points, grew out of years of design challenges working on mdspan and executors for the C++ standard library.
This talk is about those instincts and a few others: what designing library abstractions by committee teaches you about designing extension points for an agent, where the analogy held, where it broke, and how it all applies to the ways you should be interacting with agentic coding in your day-to-day work.

C++ starts with ‘cpp'
In this keynote I will take you on a journey of seeing what happens inside a C++ compiler. I will guide you on where you should start if you want to implement your own C++ frontend from scratch, what problems you will face, and how to solve them using modern C++ language and library features.
Speakers

Contemporary C++ Testing
It’s been 15 years since Catch claimed to be a “Modern C++ Testing framework”. C++ has been through some game changing stages of evolution in that time. What would a test framework built for the C++ of today look like? Can we do even better?

What’s New in Undefined Behavior
Undefined behavior (UB) has long been one of the most consequential — and misunderstood — aspects of the C and C++ programming languages.
This presentation examines the definition, classification, and practical implications of undefined behavior in these languages and how these concepts are evolving.
The talk begins with a precise characterization of undefined, unspecified, and implementation-defined behavior, and explains how undefined behaviors arise.
It then explores why standards committees designate certain behaviors as undefined.
The presentation then details recent standardization progress, C++ ill-formed no-diagnostic-required (IFNDR) programs, and a taxonomy of strategies for eliminating UB

Debugging constexpr Evaluation
Modern C++ keeps pushing more logic into constexpr/consteval: parsers, tables, DSLs, hashing — code with branches, state, and failure modes that happen before your program ever runs. When something goes wrong at compile time, you can either try to guess the reason from the compiler’s notes or de‑constexpr it… and hope the runtime reproduction matches what the compiler actually did.
In this talk, we’ll treat compile-time execution as something you can debug rather than guess. We’ll step through constexpr evaluation, inspect values as they evolve, and see which if constexpr branches fired. We’ll look at what the compiler “sees” — call stack, locals, recent returns and template arguments — to find where an expression stops being a constant expression.
We’ll also look under the hood at how tools can make constexpr debugging possible — what state the evaluator has to track, what data structures to use and where the limits of compile-time debugging come from.

Beyond Templates: Building a Runtime-Compiled C++ Engine for GPU Data Processing
Modern C++ developers are accustomed to choosing between compile-time abstraction and runtime flexibility. But what happens when users need to define arbitrary expressions that don’t exist when the application is built?
In this talk, we’ll explore how the RAPIDS cuDF team built a JIT-compiled expression engine that generates CUDA kernels at runtime, enabling arbitrary user-defined transformations while retaining near hand-written performance.
Using real examples from cuDF’s evolution, we’ll compare three approaches to expression evaluation:
Precompiled operator pipelines AST-based interpreters Runtime-generated CUDA kernels using NVRTC
We’ll examine why AST interpreters eventually hit scaling limits, how kernel fusion changes memory behavior on GPUs, and how runtime code generation unlocks support for complex operations such as string processing and conditional expressions.
Along the way we’ll cover practical engineering challenges that every C++ developer encounters when building JIT systems:
Representing expressions as trees Generating valid C++ from an AST Runtime compilation with NVRTC Managing compile latency and caching Debugging generated code Balancing flexibility against compilation overhead
Attendees will leave with a concrete understanding of how modern C++ systems can combine static performance with dynamic behavior, and how JIT compilation techniques can be applied far beyond databases and scripting languages.

Refactoring Towards Structured Concurrency
The addition of “Senders and Receivers” (a.k.a execution) to C++26 is a nudge for C++ practitioners to consider utilizing Structured Concurrency princinples when designing and implementing concurrent systems. Structured Concurrency is a well reasoned methodology, described by various C++ experts in the past, focused on composability, wide applicability, error tollerance and on correct fit with the rest of the language, most notably C++20 coroutines. The challenge that we’ll face in this talk is that of taking existing concurrent and systems which were not originally designed with Structured Concurrency in mind, and making the gradual changes towards that design and towards more natural use of senders, receivers and coroutines. Join me in a tour of various techniques and tips for modernizing legacy concurrent systems, as we prepare for adopting the C++26 standard.

C++26 Reflection
C++26 finally introduces reflection. Something C++ developers have long waited for. Yet, opposed to languages like Java and C#, C++’s reflection is compile time. This talk explores what becomes possible when types, members and enumerators are no longer opaque to your code. From eliminating boilerplate to expressing ideas that were previously off the table entirely. If you’ve ever written a macro to do what the language should have done, you’re gonna like this talk.

State Machines in C++26: From Switch Statements to Compile-Time Reflection
State machines are everywhere: embedded devices, protocol stacks, control systems, games. Yet C++ still offers no single obvious way to implement them, and every approach trades off readability, performance, and maintainability differently. In this talk we take a structured tour through the classic implementation strategies — switch-based dispatch, transition tables, and class-based designs à la the State pattern, with a look at std::variant and library solutions along the way. For each, we compare interface ergonomics, code size, dispatch overhead, and debuggability, with measurements rather than folklore. Then we turn to C++26. Static reflection changes the picture: transition tables can be generated and validated at compile time, states gain readable names in logs and debuggers at no cost, and incomplete transition handling is caught during compilation rather than in production. You will leave knowing which technique fits your constraints today, and how C++26 lets you combine the performance of hand-written dispatch with the safety and expressiveness of a framework — without the framework.

Kinds of Invariants
Software invariants are the “always true” properties that keep systems predictable: assumptions about memory, states, inputs, concurrency, and environment that must hold before and after every meaningful operation.
This talk reframes invariants as a practical safety instrument, because most severe failures happen when code silently drifts outside its intended validity envelope and the program is free to do something surprising. We’ll connect three themes: Safety (preventing catastrophic outcomes), Validity (making intended states explicit and checkable), and Undefined Behavior (what happens when an invariant is violated and the language/optimizer stops guaranteeing anything).
We’ll then map a spectrum of invariant techniques – from types, ownership, and API design; to static analysis and compiler flags; to runtime assertions and property-based tests, showing where each best fits in real systems.
Finally, we’ll discuss organizational leverage: adopting memory-safe components and invariant-first interfaces reduces the burden on downstream testing and incident response, aligning engineering velocity with security posture.

AI writes all your code now, how will you ever debug it?
With agents we’re writing more code than ever but, with only the code to reason from, they do a terrible job of explaining what happens when it runs. In this talk we’ll give a broad overview of the current best practices for helping an agent explain the runtime context of your program so your agent can actually debug what you’ve created – and talk about what might be coming in the future.

Concurrent Data Structures for Modern Hardware
The conventional wisdom about lock-free programming has quietly inverted, and it changes how you build concurrent containers. Under high contention, a well-written spinlock beats lock-free atomics and CAS loops, often by a wide margin: contended lock-free operations flood the cache-coherence interconnect, while a spinlock serializes access cleanly and lets the rest of the machine get on with useful work. Under low contention, the result flips just as decisively — the implicit synchronization a spinlock imposes, even completely uncontended, disrupts a modern out-of-order pipeline far more than a single atomic read-modify-write. High contention wants a lock. Low contention wants an atomic. This talk spends its first few minutes restating that result—the graphs, the two-line explanation, and the cross-architecture benchmarks. Then we move past it to the real question: if you take that rule seriously as a design constraint, what does a concurrent data structure library actually look like? Fewer moving parts than you’d expect. Almost every structure that follows is composed from just three primitives: * Spinlocks, for the small number of genuinely hot contention points. * CAS loops (or wait-free operations, where the algorithm allows), for contention spread thin across a large structure. * A publishing protocol — the front half of RCU (read-copy-update), reclamation deliberately left out of scope — for safely handing a newly installed pointer to a reader. The choice between the first two isn’t a matter of taste. A queue has a couple of fixed contention points, head and tail, that a spinlock covers cheaply; a list or a hash table scatters contention across every node, which is exactly where lock-free composition wins instead. Seen this way, a lot of “advanced” lock-free data structures stop looking like separate inventions and start looking like the same three ideas wired up differently. We’ll build from simple to advanced. Two of the containers set up the method: * A lock-free list — the composition pattern in full view, end to end. * A thread-safe, random-access container (deque-like), with non-locking access on the hot path. Then the MPMC queue — the structure this crowd actually keeps score with. An MPMC queue is the unofficial proving ground for concurrency work: hard enough that beating the field means something, common enough that plenty of people have tried. This one is a dual-domain design that segregates the contended path from the uncontended one, and its median latency beats every published lock-free queue I’ve measured it against by roughly 10x. The caveat is the honest one you’d expect from a lock-based design: it gives some of that back at the tail, 99.9th percentile and beyond. We’ll walk through the design and where exactly the tradeoff lands. The capstone is harder still: * A hash table with non-locking rehash. Inserts proceed without blocking while existing elements are relocated to their new slots underneath them — a genuine test of whether the three primitives compose the way the theory promises. If you’ve ever treated advanced concurrent data structures as impenetrable black boxes, this talk is meant to change that. You don’t need a PhD in lock-free algorithms to build world-class concurrent containers — you need three primitives and a clear rule for which one an access pattern is actually asking for. You’ll leave with the parts bin, not just the parts.

Several easy ways to increase the quality of your code, make them yours
There are many easy-to-use tools, that help us improve the quality of our code. Nevertheless, there seem to be developers who are not familiar with those tools or don’t use them. Why ? If the machine can have our back, with quick feedback loops, we should take advantage of that. The compiler is your best friend, tweak the warning levels up. Or should we say: compilers are your best friends. The next step is static analyzers, once again have the machine inspect your code, no personal preferences to discuss in code reviews, the machine won’t budge or become emotional. We will look at cppcheck and clang-tidy. Also at run time we have a few friends to help us out, the sanitizers do an excellent job at finding issues, we will look at valgrind, UBSAN, ASAN, TSAN. There are many ways to use these tools, we will look at a way, but there are other ways, find your way in case you don’t like the presented way, as long as you start using the tools. We will also look at a way to integrate these tools into the cmake/ctest Eco-system.

Low Latency in a Multithreaded World
Modern applications rely on concurrency to scale, but more threads do not automatically produce lower latency. Contention, synchronisation and false sharing can introduce unpredictable delays, especially at the tail.
This talk explores practical techniques for building low-latency systems in a multithreaded environment. We’ll build a framework from the ground up, focusing on composability and ensuring that threads can communicate efficiently. Along the way, we’ll develop a set of guidelines for approaching multithreaded challenges.
