Posts
Flagship technical posts and short-form community items, newest first.
Reflection can flag a dangling signature that GCC 16.2 does not warn about
A reflection lint of under 60 lines flags 3 of 5 declarations in a namespace on GCC 16.2: two return a view of a by-value owner, one returns a reference that can bind a temporary. For the view case GCC 16.2 gives no warning with -Wall -Wextra, a plain run prints garbage, and AddressSanitizer reports a heap use after free.
A type that is trivially copyable and cannot be copied
std::is_trivially_copyable answers a narrower question than its name suggests. There is a type for which it is true while the type is neither copy-constructible nor copy-assignable, MSVC says so, GCC and Clang disagree, and the paper that documents it says MSVC is the one following the standard.
Catch2 3.16 fixes a bug that shipped with the feature
A maintenance release with no new API. The interesting entry is that catch_discover_tests has been splitting test names containing semicolons since the first version of the script, which is a long time for a bug to survive by only affecting people who punctuate their test names.
Read what three September pages say about Rust and Swift meeting C++
Three September 2026 pages describe toolchain work at the Rust and Swift boundary with C++: a Microsoft guest post, a Rust Foundation interop update and the Swift 6.4 release post. This post says what each page states, what it leaves out, and that the Swift page names no compiler flags.
Profiles now run on Compiler Explorer: what P4415R0 reports and what I ran on both builds
P4415R0 reports two working implementations of C++ profiles, one in a Clang fork and one in a GCC fork, both on Compiler Explorer. I ran examples from the paper on both builds on 25 October. The GCC build rejects an unmarked owning factory, a leaked owner, a vector pointer used after push_back and a returned local address under the invalidation profile. The Clang build has no such profile and compiles the same file without complaint.
Sort a QRangeModel in Qt 6.12 without a proxy model
Qt 6.12.0 on Compiler Explorer sorts a std::vector of tuples through QRangeModel::sort(), and the same program on Qt 6.11.0 leaves the order unchanged. The post reports what the Qt 6.12 LTS pages say about QRangeModel, Canvas Painter, QtGrpc compression, the C++17 requirement and the 5-year maintenance period.
Constexpr constructors with virtual bases work in GCC 16 and Clang trunk
P3533R2 lifts the rule that a constexpr constructor cannot belong to a class with a virtual base. GCC 16.1 accepts it with -std=c++26 and Clang trunk accepts it, while GCC 15.3 and Clang 23.1 reject it. One case still differs: GCC 16 refuses a virtual call through a reference to the virtual base in a constant expression, and Clang trunk accepts it.
MSVC 14.52 release candidate: C++23 mode ready for production, and constexpr cmath behind an opt-in
Microsoft's release candidate of MSVC Build Tools 14.52, announced on 15 October, calls the C++23 mode ready for production and the STL C++23 feature complete, after constexpr cmath and cstdlib. The stable release is expected in November with Visual Studio 18.12. Compiler Explorer's newest MSVC, v19.51, rejects both new options and fails a constexpr std::sin, which shows what changes.
Replacing moc with reflection: 35 of 48 matrix rows match, and a class needs no macro
I listed 48 things moc processes or generates and gave each a verdict that a test must back. 35 rows are the same: 30 against a real moc's output, 5 by behaviour that moc cannot give. 7 differ in a stated way and 4 are not supported yet. A Qt class and a gadget now need no macro, because the base class finds the class through a default template argument.
Six Qt security advisories in five days: which versions are fixed, and what to do now
Between 19 and 23 October Qt published six security advisories. Two are rated high: a denial of service in QXmlStreamReader (CVSS 8.7) and one in the SVG parser (7.1). The open-source download directory for 6.11 lists 6.11.2 as the newest release, so the fixes named as 6.11.3 are not downloadable yet. This post lists all six with affected and fixed versions, and the mitigations the advisories give.
Closing the known limits of the Qt observable models
The first post listed ten limits of the observable container and its Qt models. Three tests found real defects while closing them, a hash slowdown turned out to be code placement, and a row index made a change 42 to 125 times cheaper at large sizes.
The pre-Búzios mailing has 89 papers: contracts, undefined behaviour, profiles and function-body reflection
The 2026-10 WG21 mailing lists 89 documents for the Búzios meeting of 16 to 21 November. Five papers are worth reading first: the contracts reply P4433R0, the undefined-behaviour framework P3100R9, Herb Sutter's question about profile-defined behaviour, the first profiles implementation report, and a proposal to reflect function bodies. This post says which ones I read and which I only know by title.
The C++26 DIS ballot was reported as disapproved: the numbers, the sources and the next steps
The 12-week ISO ballot on C++26 ended on 22 October. Two named people report it was disapproved: 12 of 20 P-members in favour, where two thirds are needed, and 9 of 22 votes negative, where a quarter is allowed. No WG21 or ISO document states the tally yet. This post separates what the papers prove from what is reported, and lists the four routes the rules allow.
What a C++ contract would have to be to prove something
A reader asked for contracts that prove things instead of glorified assertions. On GCC 16.2 a postcondition does not reach the caller, a body-less predicate links only when ignored, and a bad constant port is already a compile error. The chain they want comes today from a type and a visible predicate.
Catching a leftover std::function copy before it ships
Stock clang-tidy checks stay silent on a std::function moved down a by-value chain, and one of them flags the corrected code. A short custom query check finds the three bad sites, and ThreadSanitizer reports the wrong-thread destructor on libc++ when the destructor touches thread-confined state.
Two problems confirmed by the spec's author, fixed in both bindings
The author of the container spec wrote that section 8.3 is a mistake, not a trade-off, and that the lazy row map is in the real code. Both generated bindings now announce a batch removal while the entries still exist and find a row by binary search: a hash drain at 10,000 entries went from 193 microseconds per removal to 320 nanoseconds.
Deriving equality, hashing, and ordering from structure
C++20 gave us `= default` for operator== and <=>. Reflection lets us do the same for hashing, plus go beyond default: include/exclude fields, custom combinators, and floating-point tolerances. All declarative.
GCC's development branch accepts designated initializers for base classes
In June the P2287R6 example had to stay commented out because no compiler accepted it. On 2026-10-18 GCC's development branch (17.0.0 20261018) compiles B{.a = 1, .b = 2} for a derived aggregate with -std=c++29. GCC 16.1 and 16.2 in C++26 mode and Clang trunk in -std=c++2d reject it.
What C++23 and C++26 promise about a moved-from function wrapper
None of the standard function wrappers promises an empty source after a move: std::function, move_only_function and copyable_function all leave it valid but unspecified. libstdc++ 16.1 empties all three, libc++ trunk keeps a copy in std::function and does not ship the other two. A small wrapper that states its own move works on both.
Portable SIMD is in C++26, and you can try it now
C++26 adds <simd>, a portable vector type that compiles to SSE, AVX, or NEON without a single intrinsic. GCC 16.1 does not ship the standard header yet, but the experimental version it grew from works today, and the programming model is the same: declare a vector, use the arithmetic operators, let the library pick the width.
Read what the EU CRA reporting rules say, now that they apply
Reporting of actively exploited vulnerabilities and severe incidents under the EU Cyber Resilience Act has applied since 11 September 2026. This post quotes the 24 hour, 72 hour and final report deadlines from Article 14, says what the text says about open-source software stewards, and reads the Declaration of Conformity that Qt ships with commercial Qt 6.12 LTS. It is not legal advice.
Naming a constant makes GCC stop believing it is one
A C++26 expansion statement over a compile-time range works on GCC 16.1 when the range is written inline and fails when the identical expression is given a name. The error says the constexpr variable is not a constant. Clang accepts both, and the workaround is to delete the name.
228 Qt model edge cases, and the ones my models failed
I wrote down 228 edge cases for the observable Qt models and tested each one. 170 work, 22 are refused on purpose, 27 were defects that are now fixed, and 9 are still pinned. The defects included an editor that writes an empty value back, and a model that survives its container with stale rows.
Regenerating a Qt container library from a spec, with and without moc
A reader wrote their observable Qt containers down as a spec an AI agent can regenerate from. Two fresh agents built it, one with classic moc and one with typed signals through reflect-moc. Both pass all 17 acceptance entries, the moc version builds with MSVC, and the spec itself has a row lookup that costs 193 microseconds per removal at 10,000 entries.
One Qt class template can declare typed signals without moc
A Qt engineer named reflect-moc's last open limit as exactly his case: one observable container for many types, which moc cannot give signals. The cause was one line. Now one container template declares typed signals, one generic model serves seven Qt containers, and a random test with six wrong adapters and 31 mutants checks that ghost rows and ghost selections cannot come from it.
Replaying Qt Bridges' meta-object calls in C++ and diffing them against moc
Qt Bridges' Rust layer builds each class's meta-object at run time with Qt's private QMetaObjectBuilder. I replayed its builder calls on one class in C++ and compared the result with what moc generates, on Qt 6.10.3, 6.11.3 and 6.12.0. The registration API has no way to say that a property is read-only, to name a signal's parameters or to add an enum, and in the C++ analogue emitting a signal by name costs about 22 to 46 ns more than emitting it by index. Source commits, line numbers, measurements and what was not run are listed.
Two dates for the pre-Búzios mailing, Búzios 16 November, and GCC 17 stage 3 the same day
The Búzios agenda lists the pre-Búzios mailing on 19 October and the WG21 home page says 23 October. The meeting opens on 16 November, and GCC 17 stops accepting new features on that same Monday. Read from the primary pages on 6 and 10 October.
C++26 reflection runs on a compiler you already have
The received wisdom is that trying P2996 means the Bloomberg clang fork. It does not. GCC 16.1 has shipped reflection since April behind -freflection, using the standard <meta> header, and it runs the same code. The two implementations do disagree about what display_string_of prints.
Hand a task to another thread without leaving a copy behind
Two ways to stop a std::function from leaving a copy behind when it crosses to another thread: empty the source with an exchange, or box the task in a shared_ptr at the entry point. In a demo on libc++, the plain by-value chain destroys the task on the sending thread and both fixes destroy it on the worker.
Four official Qt examples build and run without moc
Four examples from Qt 6.10.3 (a QThread renderer, a QML tutorial, a widgets example and a queued custom type) were rewritten by a migration tool and built with AUTOMOC off. Each prints the same harness output as the moc build, with 0 warnings, and a build in which moc is replaced by a failing trap passes. The diffs are 14 to 111 changed lines, the tool left nothing for manual work, and the limits and the timing noise are listed.
C++26 tightened unevaluated strings, and GCC did half of it
P2361R6 makes encoding prefixes and numeric escapes ill-formed in the strings that only exist at compile time. GCC 16.1 rejects the prefixes and accepts the escapes; Clang 22.1 rejects both. The same source compiles on one and fails on the other, which is worth knowing before you rely on either.
simdjson 5.0 reads a struct from JSON keys in any order
simdjson 5.0.0 (28 Sep 2026) lists static reflection as an officially supported feature. A struct with a string, an int, a bool, a nested struct and a vector read from JSON with shuffled keys on GCC 16.2 and simdjson 5.0.2, and an integer of exactly 2^64 is now a big integer. The 1.8x speedup in the release notes covers parsing escaped Unicode.
Parsing your config file before the program exists
#embed puts a file into the translation unit and reflection enumerates a struct's fields. Together they turn a configuration file into a compile-time constant, with the keys derived from the struct rather than written twice, and a missing entry becoming a build error rather than a failed startup.
libstdc++ on GCC trunk rejects a pair that binds a temporary
On GCC trunk, building a std::pair or std::tuple whose reference member binds to a temporary is an error from C++11 to C++26. GCC 16.2 rejects it only from C++20 on. The same weeks brought a libstdc++ fix for CVE-2026-102010, now on the GCC 14, 15 and 16 branches, and a std::bitset fix that is on trunk only. Compiler Explorer runs show 16.2 and trunk side by side.
What a C++ team can actually point at when asked about memory safety
The question now arrives in procurement paperwork rather than in conference talks, and C++26 shipped without the profiles that were supposed to answer it. What exists today is less impressive and more useful: a hardened standard library measured at a fraction of a percent, sanitizers in CI, and warnings that catch the class of bug being asked about.
C++26 removes the initializer_list constructor of std::span
With the initializer_list constructor that C++26 had added, std::span<const bool> s{ptr, n} builds a two-element span of bools, and GCC 15 compiles it with a warning. P4144R1 removes the constructor, the 2026-03 LWG motion put that into the C++ working draft, and libstdc++ 16 and libc++ 23 no longer have it. Compiler Explorer runs show each library side by side.
C++26 lets you throw and catch at compile time
Until now a throw inside a constant expression was an immediate compile error, which forced constexpr code to report failure some other way. C++26 allows exceptions during constant evaluation: a throw that gets caught in the same evaluation is fine, and only an uncaught one fails the build. GCC 16.1 runs it today.
Signals, slots and thread affinity without Qt or moc
The core of reflect-moc is signals, slots, queued and blocking connections, thread affinity and a per-thread event loop in plain C++26 with no Qt. A worker thread reports progress to an object on the main thread, and the program runs on Compiler Explorer. Under ThreadSanitizer the 18 core tests passed in the recorded run, and one test reports in 27 of 11000 repeats, a report that a 12-line std::latch program without the library also gets and that a mutex and condition variable removes.
GCC trunk accepts a coroutine promise with return_value and return_void
GCC 16.2 rejects a coroutine promise type that declares both return_value and return_void. GCC trunk accepted it from 3 October 2026, implementing P3950R1 as a defect report, and now reports __cpp_impl_coroutine as 202606L. The same program on Compiler Explorer shows both results.
std::optional can finally hold a reference
std::optional<T&> was ill-formed for fourteen years, so everyone used a raw pointer and wrote a comment explaining that null means absent. C++26 makes it legal: rebinding assignment, no allocation, and a value type you can return. It compiles and runs on GCC 16.1 today, though libstdc++ has not yet set the feature-test macro.
std::function_ref borrows a callable instead of owning it
C++26 adds std::function_ref, the non-owning counterpart to std::function. It is the right parameter type for a callback you will invoke but not store: it copies nothing, allocates nothing, and binds equally to a capturing lambda or a plain function. It is to std::function what string_view is to string.
A moved-from std::function can still hold the callable
The standard leaves a moved-from std::function valid but unspecified. libc++ keeps a copy of a small callable in the source, libstdc++ empties it. A Qt HarmonyOS bug filed on 2026-10-12 shows the cost: a task queued to another thread was destroyed on the thread that sent it.
You cannot move out of a priority_queue without a const_cast
priority_queue::top() returns a const reference, so a move-only element cannot be taken out of the queue at all: the copy constructor is selected and the code does not compile. The accepted workaround is a const_cast immediately followed by pop(), which is safe for one specific reason worth understanding before you write it.
A Q_OBJECT that never names its class
RQT_OBJECT is written like Q_OBJECT: no class name, no base class template, no registration call. It finds its class by asking std::meta::current_function() for its parent from inside member functions defined in the class body. RQT_PROPERTY takes the exact Q_PROPERTY text, stringifies it and parses it with a consteval function, so a misspelled keyword stops the build with a message. A Qt-free reduction of both runs on Compiler Explorer.
A tiny ORM: struct to SQL via reflection
Diesel / Entity Framework ergonomics in C++: annotate a struct, generate CREATE TABLE, SELECT, INSERT, UPDATE, and a row-to-struct binder. No codegen tool, no intrusive macros.
What compile-time regex costs, measured
Moving work to compile time moves the bill there too. Including the CTRE header costs about three quarters of a second, and each distinct pattern adds to that. The library also declines some PCRE syntax and reports it through an error message that names the offset while wrapping it in template noise.
Three September 2026 WG21 papers return to the C++26 contracts dispute
The September 2026 WG21 mailing carries P4238R1, P4272R0 and P4381R0, three papers about the C++26 contracts feature and how it was reviewed. This post says who wrote each, when, and what it asks. Corrected on 10 October 2026: the ISO ballot closes around 23 October, not 27 September.
C++26 cannot write a signal's body, so a signal became a data member
A Qt signal is a function whose body moc generates, and C++26 reflection cannot generate a function body. A callable data member does not connect, a source_location tag gives every signal the same type, and a closure tag has internal linkage. What held is a bodyless data member that finds its owner through a hidden first member: 8 bytes per signal and 8 per class, measured. A static signal costs 0 bytes and has one silent pitfall. A signal that writes its own one-line body costs nothing and is the one form for overloaded signals.
Quantities and units on the road to C++29
Everything this series showed is also a proposal: P3045, Quantities and units library, targets C++29 with mp-units as its reference implementation, led by Mateusz Pusz of Gdansk, an ISO C++ committee voting member since 2017. The series finale looks at what standardization takes, and at the Gdansk author behind the proposal.
EDG's C++ front end is open source, and Compiler Explorer builds it with reflection
The EDG C++ front end went open source on 30 September under the Apache 2.0 licence with LLVM exceptions, with the C++ Alliance as fiscal sponsor. Compiler Explorer added EDG 7.0 and trunk builds with P2996 reflection switched on the same day. One struct-walking snippet gives the same output on EDG, GCC 16.2 and clang-p2996 apart from one type spelling, and EDG rejects template for.
Making your own type allocator-aware needs a second constructor
Put a pmr::string inside your own struct and it will allocate from the default resource unless the struct is allocator-aware: an allocator_type, an optional allocator argument in every constructor, and forwarding to members. This is uses-allocator construction, shown reaching a string nested in a pmr::vector. Episode 7 of the pmr series.
views::concat iterates several containers as one range
C++26 adds std::views::concat, a view that presents several ranges as a single sequence without copying any of them. The containers can be different types holding the same elements, the result composes with every other adaptor, and GCC 16.1 ships it today.
The hardened standard library turns an out-of-bounds read into a stop
GCC checks an out-of-bounds vector::operator[] at -O0 and stops checking at -O2, so the build you debug is guarded and the build you ship is not. One macro carries the check into the optimised build: -D_GLIBCXX_ASSERTIONS for libstdc++, _LIBCPP_HARDENING_MODE for libc++, _MSVC_STL_HARDENING for the MSVC STL. Google has reported this class of hardening cut its production segfault rate by about a third.
Qt accepts a QMetaObject that C++26 reflection built
Qt 6.10 builds its meta-objects from constexpr tables, so a table made by C++26 reflection goes in the same place. Stock Qt connects, invokes, reads properties of, casts to and binds in QML a class that moc never saw, and a differential test finds its QMetaObject identical to the one moc generates. Four things had to be worked around, and a signal's declaration had to change.
Four range views headed for the standard library
The 2026-07 mailing adds a concentrated wave of range adaptors: views::unique for adjacent duplicates, views::take_last and views::drop_last for tail slicing, and views::cycle for endless repetition. None ship yet, so the demo is what you write today to get the same results, which is exactly the boilerplate each proposal collapses into one named view.
std::array became compile-time in pieces, and the algorithms went last
std::array's own members have been constexpr since C++17, but sorting one at compile time only became possible in C++20, when the algorithms caught up. That two-standard gap is why older lookup-table code hand-rolls its sorting. Here is a table built, squared and sorted entirely during compilation.
One function that fills any struct from any pattern
A regex with N captures already describes a record with N fields, and C++26 reflection can enumerate a struct's fields. Joining them gives a parse_into<T, Pattern>() that fills any aggregate with no per-struct code, which builds and runs today on the reflection fork.
Humble Bundle sells 21 Packt C++ ebooks for €16.35 until 12 October
Humble Bundle's C++ Programming Masterclass sells 21 Packt ebooks, DRM-free in PDF and EPUB. The floor is €4.53 for three books, €13.62 unlocks seven, and €16.35 unlocks all 21. Part of each purchase goes to The Global FoodBanking Network. It ends on 12 October at 18:00 UTC. The strongest titles are by Fedor Pikus, Marius Bancila, and Patrice Roy with Michael Wong; most target C++20 or C++23, one is about C and one about Rust.
reflect_soa: AoS → SoA → AoSoA, one struct, three layouts
Corrected on 6 October 2026: reflect_soa is not a published library (its repository holds only a README), the embedded demo is a reduced hand-written stand-in, and the benchmark timings were never measured and are removed. The correction at the top has the details; the rest is kept as published.
Reflection across languages: C++26 vs Rust, C#, Java, TypeScript, Go, Python
Capstone: the canonical reflection tasks — serialize, enum↔string, CLI parsing, ORM row binding — side by side in seven mainstream languages. Where C++ lands, and what the uniquely-C++ angle actually gives you.
When two enumerators share a value, the value carries both names
With red = 1 and green = 1, a reflection-based enum_to_string(green) returns "red", because once the value is in a variable nothing distinguishes the two. C++26 reflection can list every name for a value, reject duplicates at compile time with std::meta::exception, prefer a canonical spelling through an annotation, and keep the exact name when you reflect the enumerator itself. The names come back as string_views over static storage, so none of this allocates.
Replacing Qt's MOC with reflection
Qt's Meta-Object Compiler parses Q_OBJECT/Q_PROPERTY declarations and emits glue code. With C++26 reflection, Q_PROPERTY-equivalent becomes a library pattern — no external compiler, no generated files.
define_aggregate: synthesising types at compile time
TypeScript's Pick, Omit, and Partial have direct C++26 equivalents. define_aggregate lets you construct a new type from a list of member specs — opening up type-level programming that was previously pure metaprogramming wizardry.
Auto-generated mocks from interfaces
Corrected on 5 October 2026: reflection cannot generate the mock class this post describes, because define_aggregate adds data members and no functions. The correction at the top has the GCC errors; the rest is kept as published.
Autowired dependency injection: no container, just reflection
Spring's and .NET's DI containers, reimplemented as a 60-line C++26 library. Reflect constructor parameters, resolve them from a type registry, compose.
A lexer that is one pattern and no allocations
An alternation where each branch is a capture group doubles as a token table: whichever capture engaged names the token kind. Built on tokenize, unmatched input stops the scan instead of being skipped, which is what a lexer wants. The whole thing runs at compile time as readily as at run time.
CUDA lock-in is real, and it is not in the C++
The usual account says CUDA's warp primitives and template layers weld your code to Nvidia hardware. Compile the same kernel through a third-party toolchain for an AMD GPU and the warp shuffle comes out as native cross-lane instructions with the addition fused in. What binds you is the toolchain and the licence, not the language.
Clap for C++: turning structs into command-line parsers
Rust's clap-derive in C++: declare a struct, get a working argv parser with --flags, -short options, help text, subcommands. One attribute per field, zero manual dispatch.
One codegen, many wire formats
JSON, YAML, XML, TOML, MessagePack — all from the same annotated struct. Factor format-specific syntax into a policy object, share the reflection walk, ship N formats for the cost of one.
Deserialization and std::expected: completing the round-trip
Parse JSON into a typed C++ struct with precise per-field error reporting via std::expected. Reflection + template for + annotations — the same machinery, just running the other way.
Annotations: tag-driven serialization comes to C++
P3394 brings serde-style and Jackson-style attribute programming to C++: rename, skip, skip_if_empty, rename_all — all as plain user-defined values queryable by reflection.
A 40-line JSON serializer with reflection
Corrected on 6 October 2026: there is no reflect_json library, and the speed figures in the first version were not measured with a method I can show. The post walks a struct and emits JSON in about fifty lines, with no macros and no external codegen; the corrected measurement is in the Runtime cost section.
228 of 2,613 tracked C++ projects now ship a module
The arewemodulesyet tracker lists 228 projects with a C++20 module, up from 62 in November 2025. That is 8.7% of the 2,613 it follows, and a tick means a module exists, not that it is on: two of three well-known entries keep it behind a build option that defaults to off. A single-file import std; builds on Compiler Explorer only with GCC 16 and one extra flag.
Four CppCon 2026 keynotes are already free to watch
CppCon 2026 closed on Friday and four keynotes are already on YouTube as unlisted prerelease links, including the first panel keynote the conference has run. The rest of the programme sits in paid Early Video Access for at least 30 days before the free drip to YouTube begins, one Main Program talk per business day.
Iterating matches, and a manual that has fallen behind
search_all, split and tokenize cover scanning, separating and lexing, and the difference between the first and the last one decides which you want. The documentation still teaches ctre::range, which the compiler now reports as deprecated, so this episode is written against the header.
The unit travels with the value
Every codebase has a comment like 'speed in m/s' that stopped being true two refactors ago. mp-units plugs quantities into std::format so the unit is printed from the type, with format specs that address the number and the unit separately. Change the unit and the log line follows. Episode 5 of the mp-units series.
A new unit in one line
In 1958 MIT students measured the Harvard Bridge in the body lengths of Oliver Smoot: 364.4 smoots plus one ear. Teaching mp-units the smoot, symbol, exact conversion factor and all, takes one line, and conversions, printing, and derived quantities work immediately. Episode 4 of the mp-units series.
Points are not deltas
The temperature is 21 degrees and the temperature rose by 21 degrees are different quantities, and adding two of the first is meaningless. mp-units models this with the affine space: quantity_point for absolute readings, quantity for changes, and the nonsense operations do not compile. Episode 3 of the mp-units series.
One per second is not one per second
Frequency (Hz), radioactivity (Bq), and angular velocity (rad/s) all share the dimension 1/s, so a dimensions-only units library happily adds a monitor's refresh rate to a radiation reading. mp-units pioneered quantity kinds: same dimension, different meaning, and mixing them does not compile. Episode 2 of the mp-units series.
The unit bug that crashed into Mars
In 1999 the Mars Climate Orbiter was lost because one team's software spoke pound-force seconds and another's expected newton seconds. mp-units, a C++ quantities library, makes that whole bug class uncompilable. First post of a series that follows the library to its C++29 standardization bid.
WG21 now says new library types must ship a pmr alias
The worry that pmr is a C++17 experiment the committee abandoned is backwards. WG21's 2024 policy P3002 makes pmr the default vehicle for new allocating types, P1083 brings resource_adaptor in C++26, and P3153 makes optional allocator-aware. A live resource_adaptor demo bridges a classic allocator. Episode 8 of the pmr series.
Getting values out of a match
Numbered captures, named captures, and structured bindings that destructure a match directly. C++26 lets the binding itself be the condition, which removes the trailing test, though one compiler currently disagrees about that inside constant expressions.
The pmr crash is the buffer that died first
The most common pmr crash rarely comes from a custom resource; it is lifetime. The container deallocates back into its resource on destruction, so the resource must outlive it. A live demo shows the destruction order and the declaration-order rule that keeps it correct. Episode 6 of the pmr series.
Move-assigning pmr containers across arenas deep-copies
Move assignment should be an O(1) pointer steal. For pmr containers with different resources it cannot steal the buffer, so it allocates in the destination and copies every element, turning a move into an O(n) copy the type system cannot warn about. Episode 5 of the pmr series.
Copying a pmr::vector silently drops its allocator
A pmr::vector looks like a value type, but copy construction does not copy its allocator: select_on_container_copy_construction returns the default resource, so a copied container silently allocates from the global heap. The propagation traits make the allocator sticky. Episode 4 of the pmr series.
Does custom allocation still pay off in 2026?
Custom allocation used to buy 44 percent. A 2026 re-run of the classic study finds modern allocators like mimalloc have closed most of that gap, so a pmr arena now earns its place for predictable latency and fragmentation resilience rather than raw throughput. With a live allocation-count demo. Episode 3 of the pmr series.
A pmr::vector on a stack buffer never calls new
The HFT and game-loop promise of pmr, made testable: override operator new to count heap allocations, then fill a pmr::vector from a monotonic_buffer_resource backed by a stack buffer with null_memory_resource upstream. Ten thousand pushes, zero heap calls. Episode 2 of the pmr series.
std::pmr is one abstract class with three functions
The whole std::pmr framework is one abstract class, std::pmr::memory_resource, with three functions to override: allocate, deallocate, is_equal. A dozen-line logging resource shows a pmr::vector's allocations, then a monotonic_buffer_resource placed in front of it collapses them to zero. Episode 1 of the pmr series.
Validating a string before the program exists
CTRE matches run inside constant expressions, so a regex can check and parse a string literal while the compiler is still working. A malformed version string then stops the build rather than surviving into production, and the parsed result is available as a constant.
The fastest loggers do not format on the calling thread
Every fix in this series synchronizes on the calling thread. The fastest loggers do not: callers enqueue a raw record and a background thread formats and writes it. A mini producer-consumer logger, the spdlog/Quill/NanoLog numbers (around 250 ns versus 7 to 11 ns), and the crash-survivability trade-off. Episode 9 of the concurrent I/O series.
Boost and Abseil start deleting their C++14 shims
Two release notes nine days apart point the same way. Boost 1.92 tells Heap and Lockfree users that C++14 support ends here, and Abseil's August LTS deprecates absl::void_t in favour of the standard one. Both are removing code that only ever existed because C++17 was not yet safe to assume.
C++29 mode is open, and the compilers already disagree
LLVM 23.1 shipped with -std=c++2d, a mode for the standard after C++26, and GCC trunk has one too. Both report __cplusplus as 202700. They do not agree about C++26 itself: GCC says 202603, which is the ratified value, and clang still says 202400.
Meeting C++ 2026 lands in Berlin with a units-library keynote
Meeting C++ 2026 runs 26 to 28 November in Berlin, hybrid as always. Two keynotes are announced so far: Mateusz Pusz, author of the mp-units library now on its way into the standard, and Kate Gregory. For anyone following the quantities-and-units work, the library's author opening the main European C++ conference is worth a note in the calendar.
LLVM 23.1 shipped, and one of its changes is silent
Clang 23.1 landed on 25 August with partial expansion statements, modules dependency discovery, and a batch of core-issue fixes. It also elides more dead stores than 22 did, which is the one change that alters behaviour without saying anything at build time.
Defaulting a destructor costs you both move operations
Howard Hinnant's table tells you which special member functions survive once you declare one yourself. C++26 reflection can check it rather than trusting it, and the result for a defaulted destructor is the one worth internalising: a line that looks like a no-op removes move construction and move assignment.
Thread-safe is not reentrant, and the difference bites
The Qt handler contract asked for a reentrant function, not just a thread-safe one, and a std::mutex gives you the second without the first. A demo shows a thread-safe counter and a reentrant recursion that needs a recursive_mutex. The precise taxonomy: reentrant implies thread-safe, never the reverse. Episode 8 of the concurrent I/O series.
Who gets to say a feature is not ready
Contracts are in the C++26 working draft. The committee voted against removing them, decisively. Bjarne Stroustrup and four co-authors are asking again anyway, before the final ballot, on the grounds that counting votes is the wrong way to settle whether a foundational feature is finished. Both cases, from the papers.
The C++20 feature that gave CTRE its interface
Writing ctre::match<"[a-z]+"> requires a string literal to be a template argument, which C++20 allowed and every earlier standard did not. The older spelling still works and still compiles under C++17, so the two sit side by side and show exactly what the feature bought.
The hottest line is often not the one worth optimizing
A sampling profiler tells you where time is spent, which is not the same as where speeding things up would help. Causal profiling answers the second question directly, and it routinely disagrees with the first. A tour of the profilers worth knowing in 2026: Coz, Tracy, poop, samply, and plain perf.
You can see the dependency chain without running anything
Before reaching for a profiler, read what the compiler already produced. Two loops that add the same floats compile to eight adds into one register versus four independent accumulators, and llvm-mca will predict the throughput difference from that assembly without executing a single instruction. Episode 4 of the verification series.
RealtimeSanitizer checks the promise that a function never blocks
Mark a function [[clang::nonblocking]] and RealtimeSanitizer verifies at runtime that nothing inside it allocates, locks, or makes a syscall. It is the sanitizer for audio callbacks, control loops, and any deadline-bound code where a hidden malloc is a dropped frame. Episode 3 of the verification series.
The same assertion, as a unit test and as a fuzzer
Google FuzzTest lets one assertion serve as both a bounded property test that runs with your normal suite and a coverage-guided fuzzer you invoke on demand. Written against a deliberately buggy encoder, it found the counterexample without being asked to fuzz at all, and printed a regression test to paste back.
A real GoogleTest suite runs in your browser
GoogleTest is a Compiler Explorer library, so a real test binary builds and runs in the browser and prints the familiar RUN/OK report. That makes a shareable link the cheapest possible way to settle an argument about behavior. Episode 1 of the verification series, on assembling a C++ setup that catches bugs before your users do.
std::endl is a hidden flush, and clang-tidy flags it
std::endl is not a fancy newline; it is a newline plus a flush, and the flush is what costs you. A flush-counting streambuf proves that a newline flushes zero times and std::endl flushes every time. When to want the flush (crash-survivable logs), when not, and why clang-tidy flags it. Episode 7 of the concurrent I/O series.
Measuring std::regex against a compile-time matcher
std::regex has a reputation, and reputations are worth checking. Measured at its most favourable, with the pattern compiled once outside the timed loop, it takes about seventy times longer per match than CTRE. Include the construction that real code usually pays for and the gap widens by another order of magnitude. Episode 1 of a series on compile-time regular expressions and the language features that make them possible.
A C++26 structured binding that GCC and Clang disagree about
C++26 lets a structured binding declaration be the condition of an if. GCC 16.1 and Clang 22.1 both implement it and both agree on ordinary structs. Put a tuple-protocol type in the condition and evaluate it at compile time, and GCC rejects the program while Clang accepts it. The reproducer is twenty lines and needs no library.
The August 2026 C++ mailing, and the fight over contracts
Forty-eight papers, and a dozen of them are the same argument. Bjarne Stroustrup and four co-authors want the C++26 contracts design replaced before the final ballot, the P2900 authors have answered, and the committee already voted once against removal. Plus profiles, a reflection paper from Barry Revzin, and the usual crop of ranges additions.
Clang's lifetimebound warns about a copy, and that is the problem
The lifetimebound attribute lets -Wdangling see through a function call, which is how clang catches a string_view into a temporary. It has no conditional form, so a function that returns a copy on some instantiations and a reference on others has to pick between missing real dangles and warning about correct code. A proposal on the LLVM forum wants to close that gap.
C++26 contracts, and the const rule the compiler makes you learn
Contracts are one of the four headline C++26 features and they run on GCC 16.1 today. Two things surprise people on first contact: a by-value parameter named in a postcondition must be const, and what a violation actually does is a compiler flag rather than a property of your code.
GCC 16.2 is out, LLVM 23.1 is nearly there, MSVC is still finishing C++23
GCC 16.2 shipped on 7 August with more than a hundred regression fixes and no new features. LLVM 23.1 reached its third release candidate on 12 August and has not shipped. MSVC has no C++26 date. If you want to write C++26 today, the practical answer remains GCC, and this is where each toolchain actually stands.
Ship the C++20 feature and its fallback in one file
The code review that started this series ended with a portability question: use std::osyncstream where it exists, fall back to a mutex where it does not. The feature-test macro __cpp_lib_syncbuf and <version> are the tool for exactly that. One file, the best available tool on each compiler. Episode 6 of the concurrent I/O series.
std::constant_wrapper carries a compile-time value as an argument
A template parameter is a compile-time value you cannot pass as an argument. A function argument is a runtime value you cannot use as a template parameter. C++26's std::constant_wrapper is an empty object that carries a compile-time value, so it crosses that line: arithmetic on it stays constant, and the result still works as an array extent. GCC 16.1 ships it.
Carbon is still pre-0.1, with 1.0 somewhere after 2028
Carbon gets discussed as though it were an option you could evaluate. It is not one yet: the project has not reached 0.1, its own roadmap puts that at late 2026 at the earliest and 1.0 sometime after 2028, and it says so plainly. Reading the roadmap is a better use of ten minutes than another Carbon-versus-Rust argument.
Pattern matching did not make C++26
Enough people assumed pattern matching shipped in C++26 that it is worth stating plainly: it did not. P2688 missed the feature freeze and is now aimed at C++29, no shipping compiler implements it, and until then std::visit with an overload set remains the idiom. Here is what the proposal would actually give you.
{fmt} can do the whole format at compile time
FMT_COMPILE parses the format string during compilation and emits straight-line formatting code, so a format call can be a constant expression with no parsing at runtime. The 12.2 release adds a type-safe C API, a proper C++20 module target, and turns the full Dragonbox cache on by default for faster float formatting.
CppCon 2026 is onsite only, and Stroustrup opens it
CppCon runs 12 to 18 September in Aurora, Colorado, and this year there is no online track. Sessions are recorded and posted to YouTube afterwards, but nothing is streamed live, so remote attendance is not an option. Bjarne Stroustrup gives the Monday opening keynote.
Converting between std::function and copyable_function nests them
std::function and std::copyable_function are both type-erased callable wrappers and neither recognises the other. Converting between them does not unwrap and rewrap the lambda inside; it wraps the whole previous wrapper. Round-trip in a loop and every call walks a chain of indirections. In this run, 200 round trips made the same calls several hundred times slower.
std::indirect makes PImpl copyable without writing a copy constructor
PImpl with unique_ptr costs you the special members: hand-written copy operations, a destructor defined where Impl is complete, and const that stops at the pointer. C++26's std::indirect is an indirect value instead of an owning pointer, so it copies deeply and propagates const, and all five special members can be defaulted. GCC 16.1 ships it.
Two compilers, one float-to-int cast, two different wrong answers
Converting a float to an int is undefined behavior when the value does not fit, and for NaN. Nothing warns by default, and GCC and Clang produce different results for the same cast. Worse, GCC deliberately leaves the check out of -fsanitize=undefined, so you have to name float-cast-overflow to catch it.
Chrome fixed 1,072 security bugs in two releases and 97% of its code is span-clean
Chrome 149 and 150 fixed more security bugs than the previous 23 milestones combined, and 97% of first-party Chrome code now compiles cleanly under strict unsafe-buffer warnings. The strategy is worth reading closely: harden C++ aggressively, migrate selectively, and admit openly that runtime mitigations are approaching diminishing returns.
GCC will decline AI-generated contributions above the legal threshold
The GCC Steering Committee has adopted a policy declining any legally significant contribution that includes or is derived from LLM-generated content. Test cases are an explicit exception, small contributions are allowed if clearly marked, and using a model to find bugs or review patches stays permitted. Commits that had AI help need an Assisted-by tag, and only humans may submit or sign off.
std::mdspan views one flat buffer as a matrix
std::mdspan is C++23's non-owning multidimensional view. It separates storage (a flat buffer you already have) from shape (extents) from indexing (a layout), so one std::vector becomes a 3x4 matrix with real m[r, c] indexing and no copy. GCC 16.1 ships it, and Mark Hoemmen's C++Now 2026 keynote is on where it and standard parallelism go next.
std::inplace_vector is a vector that never touches the heap
C++26 adds std::inplace_vector<T, N>, a sequence container with a fixed compile-time capacity whose storage lives inside the object. It gives you a vector's dynamic size and push_back with zero heap allocation, which is exactly what embedded, real-time, and hot-path code has been hand-rolling for decades. GCC 16.1 ships it now.
A new proposal deletes your enum bitmask boilerplate
Every C++ codebase that uses a scoped enum as a flag set writes the same eight operator overloads by hand, just to get |, &, and ~ back. P4313 in the 2026-07 mailing proposes an opt-in attribute, enum class [[std::bitmask_type]], that generates all of it and keeps each bitmask a distinct type. Here is the boilerplate it removes, running today.
C++26 rewrote std::print's internals and backported the fix
std::print's per-call atomicity extends to your own types via std::formatter. How it stays both safe and efficient is a C++26 story: P3107 adds locking-aware entry points and a formatter opt-in to avoid deadlock, and ships as a backport into C++23. Episode 5 of the concurrent I/O series.
Google Benchmark runs live on Compiler Explorer
You do not need a local build to run a real microbenchmark. Add the benchmark library on Compiler Explorer, turn on execution, and Google Benchmark prints its timing table in the output pane. The demo is also the first lesson every microbenchmark teaches: without benchmark::DoNotOptimize the compiler deletes the loop you are trying to measure and reports a time near zero.
std::print does not tear the way std::cout does
The fixes so far needed cooperation or a lock. C++23's std::print gives per-call atomicity for free: a single print call never interleaves with another, the way printf never did and std::cout always could. But the guarantee is per-call, so a line split across two calls can still tear. Episode 4 of the concurrent I/O series.
The sanitizers run live on Compiler Explorer
AddressSanitizer, UndefinedBehaviorSanitizer, and ThreadSanitizer all run in Compiler Explorer's execution pane. Add one -fsanitize flag, turn on execution, and the runtime report prints in the browser: the faulting line, the allocation site, the shadow-byte map, both racing stacks. There is no cheaper way to show a colleague exactly why a bug is a bug.
static std::mutex is safe to construct, thanks to magic statics
Before osyncstream, the fix for a shared log sink was a static std::mutex. But is the static mutex itself safe to initialize under threads? Yes, thanks to C++11 magic statics: a function-local static is constructed exactly once even under a stampede. With the mutex-versus-osyncstream trade-off. Episode 3 of the concurrent I/O series.
std::osyncstream makes concurrent output atomic
std::cout garbled its own output across threads. C++20's std::osyncstream fixes it: each thread buffers a line privately and emits it to the stream atomically on destruction. One wrapper, whole lines, with one sharp edge: the guarantee holds only if every writer uses it. Episode 2 of the concurrent I/O series.
std::flat_map is just two vectors
C++23's std::flat_map is an adaptor over a sorted vector of keys and a parallel vector of values. That buys cache-friendly lookups and near-zero memory overhead, and costs O(n) insertion and aggressive iterator invalidation. It replaces std::map, not std::unordered_map, and knowing which vector trick it is tells you exactly when to reach for it.
Your std::cout logging has no data race and still tears
Qt's message-handler contract says the handler must be reentrant: called from many threads at once. Point it at std::cout and the output tears, even though the C++ standard guarantees no data race. 'No data race' and 'no interleaving' are different promises, and this series closes the gap. Episode 1 of the concurrent I/O series.
The syscall behind C++ asymmetric fences
Asymmetric fences let you pay for a memory barrier only on the rare path. The common path gets a free compiler barrier; the uncommon path calls Linux membarrier(), which forces every other thread to run a full fence for you. Ryan Chung Yi Sheng's deep-dive follows the idea from the C++ standard down to the kernel, and finds a possible crack in the wording along the way.
Less standard library, faster program
Jussi Pakkanen (creator of Meson) rewrote a subset of the C++ standard library from scratch, dropping ISO conformance to chase compile speed. Converting his real CapyPDF library to it cut compile time ~80% and binary size ~75%, and made the program ~25% faster, with no runtime penalty for the faster build.
One word, final, turns a virtual call into two instructions
A C++ Weekly episode reminded everyone of a free win: marking a class final lets the compiler devirtualize. We took the canonical example to GCC 16.1 at -O2 and read the actual assembly. Without final, GCC hedges with a runtime vtable check; with final, the whole call folds to mov eax, 42; ret. The asm is the proof.
Three small C++26 string fixes you will use every day
C++26 quietly closes three long-standing paper cuts in the string library: you can finally write string + string_view, build a stringstream straight from a string_view, and construct a bitset from a view without a temporary. None of them are flashy, all of them remove a copy or a conversion you have been writing for years. Verified on GCC 16.1 and clang-p2996.
How the C++ community is actually using AI in 2026
The question in the C++ world has shifted from whether to use LLMs to how to use them well. A roundup of where that conversation is right now: Jason Turner's three-part C++ Weekly arc on getting useful code out of AI, CppCast on teaching C++ in the LLM era, and Herb Sutter asking the uncomfortable question about agents doing harm.
CppCon 2026 puts three language designers on one stage
CppCon 2026 (Sep 12-18, Aurora CO) will host the conference's first-ever keynote panel: Bjarne Stroustrup (C++), Guido van Rossum (Python), and Mads Torgersen (C#) on one stage. Three creators of three of the most-used languages alive, comparing notes on where their languages are headed.
C++26 makes an uninitialized read a defined bug
Reading an uninitialized variable has been undefined behavior in C++ since the beginning, and compilers optimize on that assumption. C++26 (P2795) reclassifies it as erroneous behavior: still a bug the compiler diagnoses, but with a defined value and no licence for the optimizer to delete surrounding code. A poisoned-stack demo shows the same source printing garbage under C++23 and a defined 0 under C++26.
Why you can't std::format a smart pointer (and how to anyway)
A recent r/cpp question: std::cout << a unique_ptr works, but std::println("{}", that_unique_ptr) is ill-formed. There is no std::formatter for smart pointers. Is that an oversight? No -- it is a deliberate, sustained decision. Here is the why, and three ways to format a smart pointer today, all verified on Compiler Explorer.
Embed a file at compile time: #embed in C++26
Baking a file into a binary has meant a build step forever: xxd -i, a generated header, a CMake custom command that drifts. C++26 adopts C23's #embed, so a file becomes a literal the compiler reads at translation time. No codegen, no glue. Here it is running on Compiler Explorer.
Gor Nishanov (1971-2026), who gave C++ its coroutines
Gor Nishanov, the architect of C++20 coroutines, has died at 54. From the 2014 resumable-functions papers to shipping implementations in MSVC and Clang, he spent the better part of a decade turning co_await into a standard language feature. Herb Sutter remembered him as intelligent and witty, but above all kind.
Structured concurrency: what std::future never had
A std::future is a dead end: you launch it, you get() it once, and composing two of them means manual threads and locks. C++26 senders compose. when_all runs work concurrently and joins it into one result, with no mutex and no leaked threads. Here is the pattern, running on Compiler Explorer.
Hello, sender: your first std::execution pipeline
C++26 shipped three big things: reflection, contracts, and std::execution. The first two get the headlines on this blog. std::execution (P2300) is the new standard model for asynchronous and parallel work, and it is the one most codebases will reach for first. Here is the smallest pipeline that does real work, running today on Compiler Explorer.
reflect_tracing: zero-overhead spans on Maciek Gajewski's ring-buffer engine
Corrected on 6 October 2026: the library this post describes has not been published, and the timing figures in it were never measured. The note at the top says what the repository holds and what the embedded demo does. The rest is kept as published.
reflect_telemetry: compile-time Prometheus metrics from annotated fields
Corrected on 6 October 2026: the library this post describes has not been published, and its benchmark numbers were never measured. The note at the top says what the repository holds, what the embedded demo does and which code was fixed. The rest is kept as published.
reflect_dx: auto-generated debugger pretty-printers and docs
Corrected on 6 October 2026: reflect_dx is not a published library (its repository holds only a README), the two tools in this post do not exist, and reflection cannot read comments. The one working piece is a natvis snippet walk, which the embedded demo runs. The correction at the top has the details; the rest is kept as published.
Define your own function colors: compile-time caller checks with C++26 reflection
C++ already enforces function colors -- consteval, CUDA's __device__, Clang's [[clang::nonblocking]] -- but every one of them needed a compiler change. C++26's std::meta::current_function() (P3795R1) lets a callee reflect on its caller at compile time, so you can paint your own colors as a 20-line library: audio-thread safety, capability tokens, or architectural layers that refuse to compile when called from the wrong place. Here is the pattern, three professional uses, and exactly where it breaks.
reflect_optics: Haskell-style lenses for C++26
Corrected on 6 October 2026: reflect_optics is not a published library (its repository holds only a README), the embedded demo is a reduced stand-in with no pipe operator, and several code claims did not hold as written. The correction at the top has the details and the GCC results; the rest is kept as published.
Reflection + annotations for hashing: opt out of fields, not whole structs
Krystian Piekos's May 29 post on infotraining.pl shows the cleanest demo so far of P3394 annotations combined with P2996 reflection: opt structs into hashing with [[=hashable]], and opt individual fields out with [[=skipped_for_hash]]. The Hashable concept and the calculate_hash walker fit in 40 lines. No macros.
reflect_arbitrary: property-based test generators, inferred from your types
Corrected on 6 October 2026: reflect_arbitrary is not a published library (its repository holds only a README), the embedded demo is a reduced stand-in with a fixed-range random generator, and the printed shrinking output came from no test and is removed. The correction at the top has the details; the rest is kept as published.
std::rotate: how libstdc++ and libc++ actually differ
Raymond Chen's June 2026 series on The Old New Thing exposed a surprising fact: libstdc++ and libc++ implement std::rotate with completely different algorithms. libstdc++ swaps left-to-right and ends at n-1 swaps with good locality. libc++ decomposes the rotation into gcd(a, n) cycles and hits ~n/2 swaps but with poor locality. Which is faster depends entirely on your input shape.
reflect_llmschema: C++ functions to LLM tool-use schemas, at compile time
Corrected on 6 October 2026: reflect_llmschema is not a published library (its repository holds only a README), and the embedded demo is a reduced stand-in that prints a smaller JSON than this post shows. The correction at the top has the details and the real output; the rest is kept as published.
Profiles take shape, and the contract C++26 left behind comes back
The other half of the Brno safety story: a profiles framework with real syntax (attributes, not pragmas) plus two concrete profiles from Stroustrup, and P3097 bringing virtual-function contracts back after they were cut from the C++26 MVP. All target C++29.
Five small C++29 papers from Brno you will actually use
Underneath the safety headlines, WG21 Brno cleared a stack of small papers that working programmers will feel every day: designated-initializers that reach through a base class, a map .get() that does not insert, defaultable postfix operators, constexpr pointer tagging (which quietly leans on reflection), and mandatory intptr_t. All target C++29.
C++ is writing down all of its undefined behavior
The structural move at WG21 Brno was not a feature -- it was a catalogue. P3596 adds two annexes that enumerate every case of undefined behavior and every ill-formed-no-diagnostic-required corner in the standard, and P3100 turns that list into a case-by-case program to close each one for C++29. There are exactly 80 core-language UB cases, and 70% of them are memory-safety bugs.
WG21 Brno: with C++26 done, the committee turns to undefined behavior
The WG21 Brno meeting (June 8-13, 2026) was the first since C++26 was finalized, and per Herb Sutter's trip report the theme is unmistakable: catalogue and eliminate undefined behavior, push memory-safety profiles toward C++29, and finish the pieces the C++26 MVP deferred. Reflection, the headline of C++26, was not on the marquee -- and that is exactly what shipping looks like.
CUDA 13.3: tile programming in C++ without the boilerplate
NVIDIA CUDA 13.3 (May 26) adds C++ tile programming: declarative tile abstractions replace manual shared memory, synchronization, and indexing. CompileIQ autotuning uses evolutionary algorithms to tune tile sizes and memory layout per kernel (up to 15% speedup on GEMM/attention). Works on Hopper and all other supported architectures.
Could C++ handle an ABI break? The 2026 case
Two pieces dropped in the same week: Luis Caro Campos' CppCon 2025 talk arguing package managers make ABI breaks manageable, and an HFT University article claiming a 58x P99 latency gap between Rust's and C++'s stdlib. The ABI debate is back. Here is what both sides are saying, and what C++26 shipped despite the constraint.
The fastest JVM is the C++26 compiler
Koen Samyn's BeCPP talk used std::meta::substitute to transform Java bytecode into executable C++ at compile time. The compiler constant-folds the entire program. The loop doesn't run faster. It doesn't exist. This is reflection used not for serialization or enum-to-string, but as a compile-time metaprogramming substrate for building language interpreters.
C++ modules in 2026: import std works, import boost is coming, your IDE still can't
import std compiles on GCC 16.1, Clang 18+, and MSVC. Boost has a per-library module prototype showing 45% build-time reductions. But CMake support is still experimental, clangd needs a full rebuild on module changes, IntelliSense has been 'experimental' for seven years, and almost no libraries ship module definitions. For reflection users: PCH is faster than modules on GCC 16.1 today.
C++: The Documentary is now on YouTube
CultRepo's 'C++: The Documentary' had its world premiere on May 28 in New York and is now available worldwide on YouTube. The film traces C++ from Bell Labs in 1979 through the language's role in modern infrastructure. Sponsored by Hudson River Trading.
simdjson meets reflection: sb << my_struct at 6.8 GB/s
simdjson now ships a C++26 reflection backend: define SIMDJSON_STATIC_REFLECTION, and sb << my_struct serializes any aggregate at SIMD speed. The CITM Catalog benchmark hits 6.8 GB/s. Combined with P3394 annotations for rename/skip, this is the production JSON path the reflection series has been building toward.
The hidden cost of <meta> -- and the three-line fix
Vittorio Romeo measured what C++26 reflection actually costs: the <meta> header adds ~181ms per TU on GCC 16.1, but the reflection algorithm itself is ~0.07ms per enumerator. The header is 2500x more expensive than the logic. A three-line CMake PCH stanza cuts the header cost by 2.3x. Modules, surprisingly, make it worse.
The May 2026 WG21 mailing in five papers (pre-Brno, 116 total)
WG21 dropped the pre-Brno mailing in early May -- 116 papers, the largest pre-meeting mailing since the C++20 design crunch. Five papers are doing the heavy lifting for C++29's safety story (the headline axis named in P5000R1 'Direction for ISO C++29'), plus the coroutines-for-I/O work that finally got first LEWG review on the schedule. This is the table of contents for what wro.cpp will be tracking through to Brno (8-13 June).
C++ Safety State of the Union: May 2026
C++ in May 2026 has four conversations running at once: regulators (CISA, EU CRA) demanding memory-safety roadmaps; the committee fighting over how to respond (Hagenberg vote 19 profiles / 9 Safe C++ / 11 both); what actually shipped in C++26 (P2900 contracts, P3471 hardened stdlib, P2996 reflection); and what the industry actually deployed (Chrome MiraclePtr -57% UAF, Google's 0.3% perf-cost data, Apple libc++ safe-buffers). They don't talk to each other in public. This essay wires them. Pre-Brno (8-13 June) reading.
Revzin at C++Now: 'Reflection Is Only Half the Story' -- what generation looks like next
Barry Revzin's C++Now 2026 keynote (Mon 4 May, Aspen) landed the line the C++ reflection community has been circling for two years: C++26 reflection lets you OBSERVE -- the next question is what it looks like to GENERATE. The 90-minute talk is a tour of source-code-generation design space (macros, templates, Rust proc-macros, Swift macros, D mixins) and reads as the natural sequel to wro.cpp's whole 'Where this is heading' triptych framing.
What reinterpret_cast doesn't do: Fertig on std::start_lifetime_as and the C++23 escape hatch
Andreas Fertig's 2026-05-18 post (re-shared on isocpp.org) makes a pointed case: reinterpret_cast and std::start_lifetime_as look interchangeable -- but only if you don't read the abstract-machine fine print. reinterpret_cast is a POINTER operation; std::start_lifetime_as is an OBJECT-LIFETIME operation. The 5-line difference between UB-then-it-works-on-my-compiler and defined-behavior.
Sutter's BeCPP keynote: C++ added more developers in 4 years than any other language
Herb Sutter's keynote at the BeCPP Symposium 2026 (March 30, Howest, Belgium) opened with a SlashData chart almost nobody outside the room has seen yet: C++ developer population grew 72% from Q1 2022 to Q1 2025 -- from 9.5M to 16.3M. That is the biggest absolute net gain of any general-purpose language over the period. Rust grew faster in percentage (137%) but on a smaller base (5.1M total). Here is the chart, the numbers behind it, and the thesis Sutter built on top -- plus an honest read on what 'fastest growing' means when JavaScript is still bigger than the second + third place combined.
The five most useful things C++26 reflection unlocks (in effort order)
C++26 reflection looks like it requires a PhD in template metaprogramming. It does not. Five concrete projects you can build with it, ranked from five minutes to weeks. Use this as a triage when picking your first reflection-powered project.
Is std::vector consteval or constexpr? A reader's question, answered
A colleague asked: 'Is std::vector consteval and not constexpr?' Short answer: no, but the intuition is right. Long answer: the constexpr/consteval/constinit trio, the transient-allocation rule, and why std::define_static_array exists.
Reflection in the wild: April 2026 in five links
Five things happened to C++26 reflection in April 2026: GCC 16.1, Glaze v7.2, a Revzin write-up, a Lemire/Thiesen JSON talk, and one honest list of what is still not shipping.
Auto-generating std::formatter<T> for any aggregate
Rust's #[derive(Debug)] in C++: make any struct printable via std::format and std::println by dropping in one partial specialisation of std::formatter. Nested types, containers, enum names — all handled.
Glaze v7.2 vs your hand-rolled JSON: a 30-line benchmark
Glaze v7.2 ships a P2996 backend that retires __PRETTY_FUNCTION__, lifts the 128-member cap, and serializes private members. Here is when you still write your own thirty lines -- and when one call wins.
Goodbye magic_enum: enum reflection done right
A reflection-driven enum↔string library in 30 lines. No __PRETTY_FUNCTION__ tricks, no compile-time range knob, no compiler-specific behaviour — and unbounded, including enum values beyond 128.
GCC 16.1 ships C++26 reflection -- your 30-line hands-on
GCC 16.1 dropped on 30 April 2026 with -freflection. C++26 was finalized at Croydon five weeks earlier. Here is a 25-line program you can compile and run today on your laptop.
template for: iterating reflections at compile time
Expansion statements (proposal P1306) unroll a loop at compile time, instantiating the body once per element. They are the natural partner of reflection — one loop, N specialisations.
C++26 is done -- five weeks since Croydon, here's what shipped
Five weeks ago WG21 voted C++26 to publication in Croydon. The dust has settled enough to take stock of what landed, what compiles today, and what it means for the wro.cpp reflection series.
Splicing: [: r :] and putting reflections back into code
Splicing is the inverse of ^^: it takes a std::meta::info and drops the referred entity back into your source. Types, expressions, template arguments, member accesses — all round-trippable.
Your first ^^: reflecting types and walking members
Hands-on introduction to C++26 reflection: the ^^ operator, std::meta::info, and walking struct members. We take the post-1 teaser apart and rebuild it from primitives.
C++26 Reflection: What changes, and why it matters
Part 1 of the C++26 reflection series. A 40-line JSON serializer nobody could write in C++ before 2026 — plus the strategic story of why static reflection changes the ecosystem.