Herb Sutter's Blog
September 18, 2025
Yesterday’s talk video posted: Reflection — C++’s decade-defining rocket engine
My CppCon keynote video is now online. Thanks to Bash Films for turning around the keynotes in under 24 hours!
C++ has just reached a true watershed moment: Barely three months ago, at our Sofia meeting, static reflection became part of draft standard C++. This talk is entirely devoted to showing example after example of how it works in C++26 and planned extensions beyond that, and how it will dramatically alter the trajectory of C++ — and possibly also of other languages. Thanks again to Max Sagebaum for coming on stage and explaining automatic differentiation, including his world’s-first C++ (via cppfront) autodiff implementation using reflection!
I hope you enjoy the talk and live demos, and find it useful.
Here is a copy of the talk abstract…
In June 2025, C++ crossed a Rubicon: it handed us the keys to its own machinery. For the first time, C++ can describe itself—and generate more. The first compile-time reflection features in draft C++26 mark the most transformative turning point in our language’s history by giving us the most powerful new engine for expressing efficient abstractions that C++ has ever had, and we’ll need the next decade to discover what this rocket can do.
This session is a high-velocity tour through what reflection enables today in C++26, and what it will enable next. We’ll start with live compiler demos (Godbolt, of course) to show how much the initial C++26 feature set can already do. Then we’ll jump a few years ahead, using Dan Katz’s Clang extensions, Daveed Vandevoorde’s EDG extensions, and my own cppfront reflection implementation to preview future capabilities that could reshape not just C++, but the way we think about programming itself.
We’ll see how reflection can simplify C++’s future evolution by reducing the need for as many bespoke new language features, since many can now be expressed as reusable compile-time libraries—faster to design, easier to test, and portable from day one. We’ll even glimpse how it might solve a problem that has long eluded the entire software industry, in a way that benefits every language.
The point of this talk isn’t to immediately grok any given technique or example. The takeaway is bigger: to leave all of us dizzy from the sheer volume of different examples, asking again and again, “Wait, we can do that now?!”—to fire up our imaginations to discover and develop this enormous new frontier together, and chart the strange new worlds C++ reflection has just opened for us to explore.
Reflection has arrived, more is coming, and the frontier is open. Let’s go.
August 19, 2025
My C++ on Sea talk video posted: “Three Cool Things in C++26”
Thanks to C++ on Sea for inviting me to speak in June! The talk video is now live, linked below. It was recorded just 48 hours after the Sofia meeting ended, with key updates hot off the press.
Note: Next month at CppCon, I will be going even deeper and broader on reflection.
There, I’ll spend the full 90-minute talk surveying many different ways to use reflection, both what’s in C++26 and what we’ll add soon post-C++26. The point will be, not any one use, but the sheer number of uses, showing just how much gold lies in these new hills. The CppCon talk will include lots of new material I’ve never shown before, with live demos and hopefully (fingers crossed) a special guest on-stage to help showcase some advanced uses coming soon to a C++ compiler near you.
In the meantime, I hope you enjoy this video which includes a big section on that topic… thanks again to the C++ on Sea organizers and all the great attendees who gave me such a warm welcome in Folkestone.
June 21, 2025
Trip report: June 2025 ISO C++ standards meeting (Sofia, Bulgaria)

Today marks a turning point in C++: A few minutes ago, the C++ committee voted the first seven (7) papers for compile-time reflection into draft C++26 to several sustained rounds of applause in the room. I think Hana “Ms. Constexpr” Dusíková summarized the impact of this feature best a few days ago, in her calm deadpan way… when she was told that the reflection paper was going to make it to the Saturday adoption poll, she gave a little shrug and just quietly said: “Whole new language.”
Mic drop.
Until today, perhaps the most momentous single feature poll of C++’s history was the poll in Toronto in July 2007 to adopt Bjarne Stroustrup’s and Gabriel Dos Reis’ first “constexpr” paper into draft C++11. Looking back now, we can see what a tectonic shift that started for C++.
I’m positive that for many years to come we’ll be looking back at today, the day reflection first was adopted for standard C++, as a pivotal date in the language’s history. Reflection will fundamentally improve the way we write C++ code, expand the expressiveness of the language more than we’ve seen in at least 20 years, and lead to major simplifications in real-world C++ toolchains and environments. Even with the first partial reflection capability we have today, we will already be able to reflect on C++ types and use that information plus plain old std::cout to generate arbitrary additional C++ source code that is based on that information and that we can compile and link into the same program as it’s being built. (In the future we’ll also get token injection to generate C++ source right within the same source file.) But we can generate anything: Arbitrary binary metadata, such as a .WINMD file. Arbitrary code in other languages, such as Python or JS bindings automatically generated to wrap C++ types. All in portable standard C++.
This is a Big Hairy Deal. Look, everyone knows I’m biased toward saying nice things about C++, but I don’t go in for hyperbole and I’ve never said anything like this before. Today is legit unique: Reflection is more transformational than any 10 other major features we’ve ever voted into the standard combined, and it will dominate the next decade (and more) of C++ as we complete the feature with additional capabilities (just as we added to constexpr over time to fill that out) and learn how to use it in our programs and build environments.
We now return you to our normal trip report format…
The meetingToday the ISO C++ committee completed the feature freeze of C++26, in our meeting in Sofia, Bulgaria. This summer, draft C++26 will be out for its international comment ballot (aka “Committee Draft” or “CD”), and C++26 final fit-and-finish is on track to be done, and C++26 set in stone, two more meetings after that in March 2026.
This meeting was hosted by Chaos and C++ Alliance. Our hosts arranged for high-quality facilities for our six-day meeting from Monday through Saturday. We had about 200 attendees, about two-thirds in-person and the others remote via Zoom, formally representing nearly 30 nations. At each meeting we regularly have new guest attendees who have never attended before, and this time there were 25 new first-time guest attendees, mostly in-person, in addition to new attendees who are official national body representatives. To all of them, once again welcome!
The committee currently has 23 active subgroups, 13 of which met in 7 parallel tracks throughout the week. Some groups ran all week, and others ran for a few days or a part of a day, depending on their workloads. Unusually, there were no major evening sessions this week as we focused on completing the feature set of C++26. You can find a brief summary of ISO procedures here.
More things adopted for C++26: Core language changes/featuresNote: These links are to the most recent public version of each paper. If a paper was tweaked at the meeting before being approved, the link tracks and will automatically find the updated version as soon as it’s uploaded to the public site.
In addition to fixing a list of defect reports, the core language adopted 10 papers, including the following… the majority were about reflection:
Reflection, part 1: P2996R13 “Reflection for C++26” by Wyatt Childers, Peter Dimov, Dan Katz, Barry Revzin, Andrew Sutton, Faisal Vali, and Daveed Vandevoorde. This is the “basic foundation” – it does not include reflecting everything yet, and doesn’t include generation (code injection), but it’s a solid and very usable first step.
Reflection, part 2: P3394R4 “Annotations for reflection” by Wyatt Childers, Dan Katz, Barry Revzin, and Daveed Vandevoorde adds the ability to reflect additional attribute information, which makes reflection much more customizable and flexible. Definitely check out the examples in the paper.
Reflection, part 3: P3293R3 “Splicing a base class subobject” by Peter Dimov, Dan Katz, Barry Revzin, and Daveed Vandevoorde adds better support for treating base class subobjects uniformly with member subobjects, again making reflection more usable.
Reflection, part 4: P3491R3 “define_static_{string,object,array}” by Wyatt Childers, Peter Dimov, Barry Revzin, and Daveed Vandevoorde adds functions that were split off from the main reflection paper P2996, which make it easier to convert reflected data to run-time data.
Reflection, part 5 (notice a theme yet?): P1306R5 “Expansion statements” by Dan Katz, Andrew Sutton, Sam Goodrick, Daveed Vandevoorde, and Barry Revzin adds “template for” to make it easy to loop over reflection data at compile time.
Reflection, part 6 (but wait there’s more): P3096R12 “Function parameter reflection in reflection for C++26”[sic] by Adam Lach, Dan Katz, and Walter Genovese adds support for, you guessed it, reflecting function parameters.
We also added a couple of other things, including that virtual inheritance is now allowed in constexpr compile-time code, and removed undefined behavior from the preprocessor as part of the current wave-in-progress of attacking and resolving undefined behavior in C++.
Interlude: A strong recommendationYou’ll notice that this time I didn’t cut-and-paste a few illustrative code examples for each paper. That’s because I strongly recommend you make time to read all the motivating code examples in all the above-linked reflection papers, to get a sense of just how game-changing this feature is, even in its current very-initial state. And those examples are just scratching the surface of what even this first step toward general reflection makes possible.
Thank you, very much, to everyone who worked so hard to bring reflection into the standard!
More things adopted for C++26: Standard library changes/featuresNot to be outdone by the core language, in addition to fixing a list of defect reports, the standard library adopted a whopping 34 papers, including the following…
P3179R9 “C++ parallel range algorithms” by Ruslan Arutyunyan, Alexey Kukanov, and Bryce Adelstein Lelbach adds what it says on the tin: parallel algorithms for the C++ Ranges library.
P2830R10 “Standardized constexpr type ordering” by Nate Nichols and Gašper Ažman makes it possible for portable C++ code to sort types at compile time.
P3149R11 “async_scope – Creating scopes for non-sequential concurrency” by Ian Peterson, Jessica Wong, and a long list of additional contributors is about enabling RAII styles to work in code that isn’t sequential and stack-based, which makes resource handling much more convenient and robust even in a heavily async world using sender/receiver, C++26’s new async model.
P2079R10 “Parallel scheduler” by Lucian Radu Teodorescu, Ruslan Arutyunyan, Lee Howes, and Michael Voss provides a standard async execution context that portably guarantees forward progress, aka an interface for thread pools.
Reflection, part 7 (you didn’t think we were done yet, did you?): P3560R2 “Error handling in reflection” by Peter Dimov and Barry Revzin enables compile-time exception handling as the error handling model for reflection code.
P3552R3 “Add a coroutine task type” by Dietmar Kühl and Maikel Nadolski provides a task type to integrate coroutines with sender/receiver, C++26’s new async model.
And much more, including constexpr shared_ptr, a bunch of std::simd extensions including enabling it to be used with ranges, and lots of other nuggets and goodies. Whew!
What’s nextThank you to all the experts who worked all week in all the subgroups to achieve so much this week!
Our next meeting will be this November in Kona, HI, USA hosted by Standard C++ Foundation.
Thank you again to the about 200 experts who attended on-site and on-line at this week’s meeting, and the many more who participate in standardization through their national bodies!
I’ll repeat what I said last time: Don’t think C++“26” sounds very far away, because it sure isn’t… the C++26 feature freeze is past, and even before that compilers have already been aggressively implementing C++26, with GCC and Clang having already implemented about two-thirds of C++26’s language features adopted so far! C++ is a living language and moving fast. Thank you again to everyone reading this for your interest and support for C++ and its standardization.
April 23, 2025
Living in the future: Using C++26 at work
I recently contributed a guest post on my employer’s blog about the importance of the almost-feature-complete C++26 draft standard:
“Sea change in C++: Why opportunities abound”
It starts by summarizing a talk I gave recently, about how C++26 is poised to do what C++11 did over a decade ago: usher in a new era of C++ code style. Just as we can now glance at 10 or 20 lines and quickly recognize “modern C++” as C++11-era code, soon we’ll be able to do the same with code that uses std::execution, contracts, memory safety improvements, and (fingers crossed) reflection, and quickly see it’s “modern” C++26-era code. A second wave of modernization, marked by a visibly refreshed language and style.
One thing I’ve appreciated here at Citadel is how aggressively the key advances are being adopted in our live trading systems. We already use C++26’s std::execution in production for an entire asset class, and as the foundation of our new messaging infrastructure. That’s possible because we’ve had our own in-house implementation running for several years now—thanks, Gašper and Bronek! Next, we’ll be pushing hard to adopt draft C++26’s new hardened standard library and contracts in our production systems, which were just voted into C++26 at our latest WG21 meeting in February.
This doesn’t mean we throw caution to the wind or reach for just any shiny new feature the moment it appears. But when key features are ready and delivering real value today, and we can get them with a little extra effort, there’s no reason to wait until tomorrow to use them. One of the nice things about that model is we get to “live in the future” by using those key features in production early, to get the benefits sooner and also to start building experience now with the cool things everyone will be using routinely everywhere soon.
The future’s not quite here. But for some features, we can already write production code as if it is. It’s illuminating; personally, I’m learning more about std::execution now that I’m in an environment where it’s being used for real. Fun times for C++!
March 30, 2025
Crate-training Tiamat, un-calling Cthulhu:Taming the UB monsters in C++
For more background on safety and security issues related to C++, including definitions of “language safety” and “software security” and similar terms, see my March 2024 essay “C++ safety, in context.” This essay picks up our story where that one left off to bring us up to date with a specific focus on undefined behavior (aka UB).
This is a status update on improvements currently in progress for hardening and securing our C++ software.
The C++ community broadly has a lot of hardening work well underway. Across the industry, this includes work being done by individual vendors, that they are then contributing to the standardization process so C++ programmers can use it portably. In the standard, it includes things we have had for a while (UB-free constexpr compile-time code) to things we’ve done recently (in draft C++26: erroneous behavior, bounds-hardened standard library, and contracts for functional safety) to proposals we’re actively pursuing next (in progress: Bjarne Stroustrup’s profiles, Úlfar Erlingsson’s remote code execution hardening).
A common underlying thread of all this work is that each piece addresses more and more of C++’s undefined behavior (aka UB), and especially the UB most exploited by attackers. We’re addressing UB methodically, starting with addressing the common high-value cases that will do the most to harden our code: uninitialized variables, out-of-bounds access, pointer misuse, and the key UB cases that adversaries need to implement remote code execution. These are the weaknesses that attackers exploit, and that we are locking down to lock them out.
Common (dis)belief: “UB is just too central to C++, trying to improve it enough to matter is hopeless”
Tech pundits still seem to commonly assume that UB is so fundamentally entangled in C++’s specification and programs that C++ will never be able to address enough UB to really matter. And it is true that it’s currently way too easy to accidentally let tendrils of silent UB slither pervasively throughout our C++ code.
Background in a nutshell: In C++, code that (usually accidentally) exercises UB is the primary root cause of our memory safety and security vulnerability issues. When a program contains UB, anything can happen; it’s common to call the whole thing “the UB dragon” and say “UB can reformat your hard drive or make demons fly out your nose” — hence the Tiamat and Cthulhu metaphors. Worse than those things, however, is that UB regularly leads to exploitable security vulnerabilities and other expensive-to-fix bugs. (For more details about UB, see the Appendix.)
So it’s valid to ask: Can and will C++ ever do enough about UB to make a major difference?
Summary and spoilersIn this post, I’m happy to report that serious taming of C++ UB is underway…
(1) Since C++11 in 2011, more and more C++ code has already become UB-free. Most people just didn’t notice.
Spoiler: All constexpr/consteval compile-time code is UB-free. As of C++26 almost the entire language and much of the standard library is available at compile time, and is UB-free when executed at compile time (but not when the code is executed at run time, hence the following additional work all of which is about run-time execution).(2) Since March 2024, the draft C++26 standard has already removed key “low-hanging fruit” run-time UB cases that were the root cause of significant categories of security vulnerabilities.
Spoiler: In draft C++26, uninitialized local variables are no longer UB, and most common non-iterator bounds errors in the hardened standard library, such as for string and vector and string_view and span, will no longer be UB in a “hardened” implementation. (And C++26 also has language contracts for a different aspect of safety, namely functional safety for defensive programming to reduce bugs in general.)(3) Now, we’re undertaking to add more tools and to systematically catalog and address run-time UB in the C++ language.
Spoiler: Addressing each case of UB statically where possible (at compile time), or with run-time checking where necessary. The primary tools: (a) C++26 erroneous behavior (EB); (b) Bjarne Stroustrup’s profiles and Gabriel Dos Reis’ profiles framework to opt into full safety by default and tactically opt out again where needed (sometimes you do want to breathe fire at a specific loop); and/or (c) applying C++26 contract assertions to check language features. EB and basic contract assertions are already part of C++26; profiles have work now underway focusing on implementation and deployment of the profiles framework and a few key profiles for experimentation across the C++ ecosystem. In addition, Úlfar Erlingsson is proposing a profile to surgically eliminate specifically the UB that attackers use to do remote code execution (RCE) which has the promise to eliminate many (and let developers opt into eliminating nearly all) malware exploits in recompiled C++ code.If successful, these steps would achieve parity with the other modern memory-safe languages as measured by the number of security vulnerabilities, which would eliminate any safety-related reasons not to use C++. Note that leveling the playing field with other languages still means there are other security issues that need to be addressed too, in all languages, such as logic bugs for functional safety (C++26 contracts will help here); we’re first addressing the most valuable target to get to parity with other modern languages and then will continue to do more.
Importantly, this approach to hardening C++ doesn’t change C++’s value proposition — it keeps C++ still C++, it doesn’t try to turn C++ into “something else” such as by requiring mandatory performance overheads. All of the above embrace C++’s existing source code and its “zero-overhead, don’t pay for it if you don’t use it” core values, and just make it convenient to make memory safety the default — always with an opt-out, so that full performance and control is always available when you want to let Tiamat and Cthulhu use their powers in your service, under your control and for good.
And it’s designed to be super adoptable to bring existing code forward:
Many of the improvements are adoptable without any code changes (really!) — just recompile your existing project with a C++26 compiler, and your code will be safer. This is important because when you write code you write bugs, and even when you write code to fix bugs you write new bugs; this is part of the cost of requiring code changes that we’d like to minimize.Even when you opt into a profile language subset that rejects unsafe code by default, you can still opt back out to writing the unsafe thing with an explicit, greppable, and auditable “suppress safety rule here” annotation (similar to “unsafe” in other languages).That’s it — if you stop reading here, you have the full story.
But I think the details are pretty interesting, so join me if you like as we dive further into the above points (1), (2), and (3)…
(1) Since 2011: constexpr codeStarting in C++11, C++’s compile-time constexpr world has already become a sandbox free from undefined behavior, quietly revolutionizing C++ by enabling powerful compile-time computation while also ensuring safety. During constexpr evaluation, the language mandates well-defined behavior — no wild pointers, no uninitialized reads, no surprises. If an operation might trigger undefined behavior, the compiler simply rejects the constexpr evaluation at compile time. This guarantees correctness before execution time, empowering developers to write faster, safer, and more expressive code.
Every release of C++ has continued making more of the language and standard library available in compile-time constexpr code, so that as of C++26 nearly the entire language and much of the standard library is available in constexpr code.
This is modern C++ at its best: unleashing compile-time power while also enforcing its correctness.
This is in production use, not vaporware: All major compilers have supported UB-free constexpr compile-time code for over a decade and it’s in widespread production use. Probably almost every nontrivial C++ project today is already using at least some UB-free constexpr code, unless it is very old code compiled with a very old compiler.
(2) Since 2024: Language safety and software security improvements adopted for C++26Over the past year, C++26 has made further solid progress on language safety and software security. Briefly, here’s what C++26 has already adopted (some of this material is repeated from my previous trip reports; see the links for much more detail and discussion):
In March 2024 (see my March 2024 trip report), draft C++26 eliminated UB for uninitialized variables by turning it instead into a new kind of behavior: erroneous behavior (aka EB) that is still considered “wrong code” (so compilers should still warn about it) but is now well-defined so it is no longer UB-dragon-bait even if your code does transgress. That eliminates one root cause of a serious class of security vulnerabilities.Last month (see my February 2025 trip report), draft C++26 additionally added a specification for a hardened standard library. Just recompiling with a hardened library gives our programs bounds safety guarantees for many common non-iterator C++26 standard library operations, including common operations on very popular standard types: string, string_view, span, mdspan, vector, array, optional, expected, bitset, and vararray. (At the same meeting, we also adopted language contracts to help improve functional safety for defensive programming to reduce bugs in general.)Importantly, both of these achieve the holy grail of adoptability: “Just recompile all your existing code with a C++26 compiler / hardened library, and it will be safer.” That’s just an awesome adoption story. If you’ve seen any of my recent talks, you know this is close to my heart… see especially this short clip from my November talk in Poland and also this short clip in the Q&A about the societal value of improving C++. Of course, getting full safety improvements will sometimes require code changes, nobody is saying otherwise — for example, if you write a dangling pointer because your code is confused about ownership then you really will need to go fix and possibly restructure your code. But it’s pretty nice that we can get a subset of the safety improvements even just by recompiling our existing code!
Again, this is in production use, not vaporware: The support for uninitialized variables and the hardened standard library may be new to draft standard C++26, but they are already well supported on existing compilers. For uninitialized variables, you can already use the pre-standard compiler switches -ftrivial-auto-var-init=pattern (GCC, Clang) and /RTC1 (MSVC). For the hardened standard library, as the P3471 authors note, it has already been deployed in major commercial environments (you can use it today in libc++, see documentation here; MS-STL and libstdc++ have some similar options):
“We have experience deploying hardening on Apple platforms in several existing codebases.
Google recently published an article where they describe their experience with deploying this very technology to hundreds of millions of lines of code. They reported a performance impact as low as 0.3% and finding over 1000 bugs, including security-critical ones.
Google Andromeda published an article ~1 year ago about their successful experience enabling hardening.
The libc++ maintainers have received numerous informal reports of hardening being turned on and helping find bugs in codebases.
Overall, standard library hardening has been a huge success, in fact we never expected so much success. The reception has been overwhelmingly positive …”
This really demonstrates the value of addressing low-hanging fruit, and the Pareto principle (aka 80/20 rule): Often 80% of the benefit comes from the first 20% of investment.
(3) Since the past month: More work ongoing in the C++26 timeframeFor about a year now, multiple C++ committee experts have independently proposed systematically cataloging and/or addressing UB in C++:
December 2023: Shafik Yaghmour’s proposal P3075R0 to catalog C++’s language UB and document it as an Annex to the standard. (Building on his earlier pre-pandemic paper P1705R1.) This was encouraged by the core language specification subgroup (aka CWG) at the March 2024 meeting.October 2024: My proposal P3436R0 to catalog UB and systematically address it using the opt-in mechanism of Bjarne Stroustrup and Gabriel Dos Reis’ language profiles proposal which has the ability to designate profiles as “named groups” of related compile-time restrictions and run-time checks that are easy to opt into to make safety the default. For more details, see my November 2024 trip report. This was unanimously encouraged by the Safety and Security subgroup (aka SG23) at the November 2024 meeting.October 2024: Timur Doumler, Gašper Ažman, and Joshua Berne’s proposal P3100R1 to catalog UB and systematically address it as contract violations, using the new C++26 contract_assert feature to perform run time checks also for problematic language features. There is a related proposal P3400 to designate contract labels as “named groups” of related run-time checks that are easy to opt into to make safety the default. P3100 was unanimously encouraged by the Contracts subgroup (aka SG21) at the November 2024 meeting.You can see the pattern: there are proposers and volunteers to
systematically catalog language UB,specify a way to eliminate the UB (make it illegal, or well-defined including where necessary with a run-time check such as a bounds check),make that elimination happen preferably all the time where it’s efficient enough (as C++26 is doing for uninitialized local variables) or else under a named group that’s easy to opt into (profile name, or contract label name), andrealizing that different UB cases need to be addressed in different ways, and we’re willing to put in the effort… no magic wand, Just Engineering.At our February 2025 meeting, the main subgroup responsible for all language evolution (aka EWG) took these suggestions and gathered them together, and the group approved a mandate to pursue
“… a language safety white paper in the C++26 timeframe containing
systematic treatment of core language Undefined Behavior in C++,
covering Erroneous Behavior, Profiles, and Contracts.”
Note that this is separate from C++26, because C++26 is now undergoing feature freeze and will spend the next year doing comment review and fit-and-finish, so we cannot now add new material (such as UB mitigations) to C++26 itself. But we want to keep our momentum and not let this important work wait for C++29, so concurrently with C++26 “in the C++26 timeframe” we intend to work on a white paper to catalog and address C++ language UB, that we hope to publish around the same time as C++26 is published.
Note: A white paper is an ISO publication that’s a flavor of Technical Specification (TS); think of a white paper or TS as a “feature branch.” The C++ committee has already published a dozen TSes since 2012, such as the concepts and modules TSes, most of which have already been merged into the “trunk” international standard (aka IS). A white paper and TS use the same process within the C++ committee, but a white paper just has less ISO red tape at the end compared to a TS so it can be published faster.
So now and over the next year or two, we’re undertaking to systematically catalog cases of UB in the C++ language to put a visible label on each fang and tentacle. Then, starting with the most important high-value targets, start deciding whether and how to address each in the most appropriate way but likely using those three tools mentioned in the mandate:
C++26 erroneous behavior, which you’ll recall the draft C++26 standard is already using to deal with uninitialized local variables.Bjarne Stroustrup’s profiles and Gabriel Dos Reis’ P3589 profiles framework which allow us to create named groups of rules and checks, so that program code can easily opt into full safety by default and tactically opt out again where needed. Efforts now underway are focusing on implementation and deployment of the profiles framework and a few key profiles for experimentation across the C++ ecosystem.C++26 contract assertions to check language features, as extended with P3400 labels which allow us to create named groups of checks.I won’t lie: This is going to be a metric ton of work. And it’s work that I think some people don’t expect C++ to ever be able to do. But I think that it is achievable, and that it will be worth it, and we appreciate and want to thank all the committee members who have already expressed interest in volunteering to help — thank you!
New a week ago: P3656 strongly encouragedGašper Ažman and I got appointed to try to organize the work. So to get this started, Gašper and I wrote paper P3656 to detail a proposed procedure and plan. On March 19, EWG reviewed this in a telecon and voted strong encouragement that
“P3656 is ‘on the right track’ with the strategy proposed for
producing a white-paper for ‘Core Language UB (and IF-NDR).’”
So here’s a quick overview of what we aim to do over the coming year or two, in the same timeframe as C++26…
First, list cases: Enumerate language UBThe goal of this part is to tag every case of language UB directly in the standard’s LaTeX sources, with at least a short description and code example. Using LaTeX tags right in the standard’s sources will let us automatically build another Annex to list the UB in one place, as the standard already does for the grammar for example. Additional detailed discussion and selected mitigations will go into the white paper.
We will also likely tag some basic attributes of each UB, such as:
have security experts tag whether it is directly exploitable, so that we can prioritize security-critical low-hanging fruit first; andtag whether it is cheap to check locally with information already available (such as null pointer dereference which is easy to check locally with ptr != nullptr) or requires more information (such as other-than-null dangling pointer dereference which is more challenging, and some UB may be too expensive to entirely remove).This also creates backpressure to reduce adding future UB, by requiring discussion and documentation in this list for any new UB proposals.
Second, list tools: Create a “non-exhaustive starter menu of tools”The idea is to make an initial list of the tool(s) we can apply to each case of UB.
The EWG mandate already included erroneous behavior (EB), profiles, and contracts as the primary expected tools, so a slightly more detailed candidate list might be:
make the UB well-defined (just fix it always, no opt-in required; this could be a run-time check);make the UB fail to compile (e.g., make it ill-formed which could change the meaning of SFINAE code that could use a different fallback path to avoid the UB path, or make it directly rejected without changing any meaning), either always or when a profile/label is enforced;make the UB deprecated, either always or when a profile/label is enforced; and/ormake the UB be EB instead, either always (as we did for uninitialized locals) or when a profile/label is enforced.This list is not exhaustive; we may find UB we want to handle using another technique, but I expect most cases of UB can be handled well using these tools.
We also intend to write some initial guidelines, for EWG to review and approve, about when to use each tool, including performance considerations, adoption hurdles (like frequency of that UB, or consequences of crashes), and other common considerations.
Third, apply: For each case of UB, say how we plan to address itIn many cases, this will require thoughtful papers, including strong implementation experience when there is a risk that performance or deployability may be difficult. My expectation is that we will find groups of similar UB that can all be handled in one paper, but the point is we want to be methodical about this… we aim to move fast, but the primary goal here is to make sure we actually unbreak things.
Fourth, group: Group UB cases into cohesive groups (profiles names / contract labels)Finally, we can identify cohesive groups of UB that programs will want to address together, which makes them easy to opt into as a unit; for example, a “bounds_safety” group could include all bounds safety-related UB. These groups can overlap; for example, the same UB fix might be selectable as part of a “bounds_safety” group and as part of a general larger “strict_cplusplus” group.
New a few days ago: Efforts in progress to lock down the specific UB that malicious code relies onRelatedly, a very interesting proposal was brought to the February ISO C++ meeting by Úlfar Erlingsson, Google’s DE for Cloud Security, P3627R0 (slides): “Easy-to-adopt security profiles for preventing RCE (remote code execution) in existing C++ code.”
Summarizing Úlfar’s premise:
We have already developed sufficient hardening implementation technology in modern compilers to effectively harden existing C++ code without code changes — not by aiming for language memory safety guarantees broadly, but by surgically targeting key UB that makes remote code execution (RCE) possible. Specifically: Stack integrity, control-flow integrity (CFI), heap data integrity, and pointer integrity and unforgeability. (Note: Úlfar was the first to efficiently implement stack integrity with strong guarantees, working with George Necula who originally designed it in CCured; and he and collaborators were the first to propose and implement CFI.)If we do nothing more than take away the UB that can be used as building blocks for RCE (even if we still allowed other corruption), then bad actors would lose most of the tools they use to gain control over execution and run their malware, and we would dramatically harden the world’s code.A key problem is that right now these technologies exist as separate features when the real benefit comes from enabling them together, and so we should standardize a profile that lets programmers tell their compilers to activate them together.On Thursday, Úlfar published a new paper elaborating these ideas: “How to Secure Existing C and C++ Software without Memory Safety” describes how these techniques could not only prevent most RCE but also generally retake control of execution away from the attackers.
It’s well worth reading. An updated paper proposing this material for C++ standardization is expected soon in the C++ committee. As Úlfar notes (emphasis added): “This is a big change and will require a team effort: Researchers and standards bodies need to work together to define a set of protection profiles that can be applied to secure existing software — without new risks or difficulties — easily, at the flip of a flag …”
Note: A related new publication updated a week ago is the OpenSSF “Compiler Options Hardening Guide for C and C++.” This is a useful guide to existing security options that are good to know about and can be used in today’s compilers. These options add a variety of warnings and mechanisms that will help with security, including some used in Úlfar’s proposal (CFI and address space layout randomization, aka ASLR). However, these options are all “best effort,” and do not promise any guarantees, even when used all together — including options needing source code changes and those with noticeable overhead. What makes Úlfar’s approach different is that it carefully selects four specific techniques designed to reinforce each other such that they establish guarantees about the nested execution of functions, and the use of heap objects and pointers. Those guarantees eliminate almost all of the specific UB that malware authors rely on, and will hold even when the remaining UB is triggered, e.g., to corrupt memory.
If the language UB white paper could achieve not only its first goal of a broad systematic cataloging and mitigation of UB (grouped into profile/label names that programmers can turn on), but also specifically a “controlled_execution_security” profile that eliminates nearly all remote code execution attacks, that would be a great outcome — and would dramatically reduce C++ software security vulnerability exposure to parity (equality) with the other modern languages.
Summary, and what’s nextAs a wise sage once said: “If you choose not to decide, you still have made a choice.”
For many years, software security may not have seemed pressing enough for C++ standardization broadly to make it a top priority, though gradual improvement has always continually occurred. But times have changed; we have been confronted with a spike of cyberattacks and cyberwar that creates serious threats to the systems we rely on to sustain our civilization, and faced stark choices: react decisively? and how? or not? Making a choice was not optional, as the sage pointed out.
We have chosen: to focus on improving C++ language safety as a priority, with the goal of achieving parity (as measured in number of security vulnerabilities) with other modern languages.
We have already accomplished a great deal. Compile-time C++ is already fully free of UB, which means a huge chunk of real-world C++ is already UB-free today. In C++26 we’re already eliminating several frequent vulnerability UB root causes, where in the language uninitialized variables are no longer UB and in the standard library many common operations on widely used types like vector and string and span and string_view are becoming bounds-safe in a C++26 hardened implementation. Although these are new to the standard, all have been deployed at scale in the field, and making them standard will make them easier to adopt even more widely. (In C++26, we are also shipping language contracts for a different aspect of safety, namely functional safety for defensive programming to reduce bugs in general.)
It’s working: The price of zero-day exploits has already increased. Now we have a path to get the rest of the way to taming UB in C++. Yes, there’s still a great deal of work ahead, but if we can make a solid push over the next one to two years we do have a real shot at systematically addressing UB in C++, including eliminating nearly all remote code execution attacks. If these efforts to cage the monsters works out even half as well as we hope, I think a lot of folks are going to be very (and I think happily) surprised.
As several other wise sages said: “Let the good times roll.”
If you’re one of the ones helping with either what’s been accomplished already and/or with our next steps above, we want to again say a big “thank you!” — your help is appreciated, and it really matters.
Thanks, very much.
Appendix: UB, brieflyHistorically, UB was allowed in C and then C++ as the basis for compiler optimizations: Compilers are allowed to assume that UB never happens and optimize your program based on that assumption. In the real world, compilers are variously aggressive about making that assumption; for a survey of what common examples the different major compilers actually do optimize in what ways at different optimization levels, see my 2020 paper P2064R0 section 3.4.
We have now been reconsidering UB for two reasons, which to me corresponds to that the UB dragon has multiple heads:
UB often has directly safety and security implications. For example, if a program sometimes tries to access out-of-bounds memory, a malicious actor can use that vulnerability to write an exploit that will install malware to steal cryptocurrency or worse.UB also has indirect safety and security implications. For example, if the compiler encounters an if/else branch and notices that one side of the branch would always encounter UB, it can not only assume that branch is never taken, but it can also assume that the condition the branch is testing is always true (or always false) and so not even test it — which is problematic if the branch was doing a deliberately-enabled safety-related contract check that the compiler ends up silently optimizing out of the compiled program so that the check is never performed at all.UB optimizations also just create mysterious ordinary bugs, such as variables that appear to be simultaneously true and false, unreachable code that gets executed anyway, and “time travel” optimizations that change code that precedes the point where the UB can happen (hence, the idea of UB ‘reaching back to modify the past’).Less of all those things, please. Over the past decade C++ has been pursuing ways to keep all our glorious optimizations but to specify the optimizability in ways other than fire-breathing mind-flaying UB.
Notes:
Addressing UB in C++ is easier to do than in C, because C is a fine language but is lower-level with fewer standard abstractions, which means it has fewer universally available alternatives to recommend and fewer standard library features that the standard can directly harden. UB is closely related to another technical concept in the C++ standard called “ill-formed, no diagnostic required” (IF-NDR). For convenience, herein I’m saying just “UB” as a shorthand for “UB and [or, including] IF-NDR.”
February 17, 2025
Trip report: February 2025 ISO C++ standards meeting (Hagenberg, Austria)
On Saturday, the ISO C++ committee completed the second-last design meeting of C++26, held in Hagenberg, Austria. There is just one meeting left before the C++26 feature set is finalized in June 2025 and draft C++26 is sent out for its international comment ballot (aka “Committee Draft” or “CD”), and C++26 is on track to be technically finalized two more meetings after that in early 2026.
This meeting was hosted by the University of Applied Sciences of Upper Austria, RISC Software GmbH, Softwarepark Hagenberg Upper Austria, Dynatrace, and Count It Group. Our hosts arranged for high-quality facilities at the University for our six-day meeting from Monday through Saturday. We had over 200 attendees, about two-thirds in-person and the others remote via Zoom, formally representing 31 nations. At each meeting we regularly have new guest attendees who have never attended before, and this time there were 36 new first-time guest attendees, mostly in-person, in addition to new attendees who are official national body representatives. To all of them, once again welcome!
The committee currently has 23 active subgroups, 13 of which met in 7 parallel tracks throughout the week. Some groups ran all week, and others ran for a few days or a part of a day, depending on their workloads. We also had combined informational evening sessions to inform the committee broadly about progress on one key topic this week: reflection wording review, and concurrent queues. You can find a brief summary of ISO procedures here.
HighlightsThis time, the committee adopted the next set of features for C++26, and made significant progress on other features that are now expected to be complete in time for C+26.
In addition to features already approved for C++26 at previous meetings, at this meeting three major features made strong progress. In the core language:
P2900 Contracts was adopted for C++26P2786 Trivial Relocatability was adopted for C++26P1967 #embed was adopted for C++26In the standard library:
P3471 Standard Library Hardening (which is also the first use of contracts) was adopted for C++26P0447 std::hive was adopted for C++26Other noteworthy progress:
P2996 Reflection is almost done its specification wording review aiming for C++26, and is expected to come up for vote for inclusion in C++26 at the June meetingLanguage safety and software security improvements adopted for C++26C++26 adopted two major features that improve language/library safety and software security: contracts, and a security-hardened standard library that has already delivered actual important security improvements just by recompiling/relinking existing C++ code (see references below).
C++26 ContractsNote: For definitions of “language safety” and “software security” and similar terms, see my 2024 essay “C++ safety, in context.”
First, years in the making, we adopted P2900R14 “Contracts for C++” by Joshua Berne, Timur Doumler, and Andrzej Krzemieński, with Gašper Ažman, Peter Bindels, Louis Dionne, Tom Honermann, Lori Hughes, John Lakos, Lisa Lippincott, Jens Maurer, Ryan McDougall, Jason Merrill, Oliver J. Rosten, Iain Sandoe, and Ville Voutilainen. This is a huge paper (119 pages) that adds preconditions, postconditions, and contract_assert (a major improvement that brings C’s “assert” macro into the language, with improvements). For an overview, see Timur Doumler’s blog post “Contracts for C++ explained in 5 minutes.” The main change last week is that the committee decided to postpone supporting contracts on virtual functions; work will continue on that and other extensions. Thanks to the coauthors, and to everyone in Study Group 21 (SG21) and the language evolution working group (EWG) and everyone who commented and gave feedback, for their hard work on this feature for many years!
Note: This is the second time contracts has been voted into draft standard C++. It was briefly part of draft C++20, but was then removed for further work.
Relatedly, P1494R4 “Partial program correctness” by Davis Herring adds the idea of “observable checkpoints” that limit the ability of undefined behavior to perform time-travel optimizations. This helps to eliminate some optimization pitfalls that range from not actually executing an enforced contract (see contracts, above) to security vulnerabilities. The paper also provides std::observable() as a manual way of adding such a checkpoint in code.
C++26 hardened standard libraryThe second is another big step for language and library safety in C++26. Recall that:
C++23 already eliminated returning a dangling reference to a local object at compile time (did you know that? try it now on Godbolt), which has already removed one common source of silent dangling.C++26 has already eliminated undefined behavior from uninitialized variables.And now in C++26…… P3471R4 “Standard library hardening” by Konstantin Varlamov and Louis Dionne provides initial portable, cross-platform security guarantees for the C++ standard library too as part of C++26. It turns some common and frequently-exploited instances of undefined behavior in the C++ standard library into a contract violation (note: that makes it also the first user of the just-adopted contracts language feature, above! yes, WG21 does try to coordinate its delivered features).
In particular, only two (2) programming language weaknesses made the top 15 most dangerous software weaknesses in the MITRE 2024 CWE Top 25 Most Dangerous Software Weaknesses — and those two are Out-of-Bounds Write (#2) and Out-of-Bounds Read (#6).
This is why I keep repeating that, yes, we need to improve C (especially) and C++ memory safety, but that is far from the only thing we as an industry need to do. As we harden one area, attackers just shift to the next slowest animal in the herd. Already, above, we are seeing more and more of the MITRE Top 25 be not programming language memory safety issues… in 2024, it’s down to just 2 of the top 15. Sure we need to fix those 2 issues and others like them, but let’s never forget that we need to fix the other 13 of the top 15 too! For more on this, again please see my “C++ safety, in context” essay.
This continues to demonstrate what I’ve explained many times: Bounds safety is the lowest-hanging fruit in terms of things we need to address first. That’s why it’s a big deal that, as of Saturday, the C++26 hardened standard library focuses on bounds safety and requires that the all of following are guaranteed to be bounds-checked:
In std::span: operator[], front, back, first, last, subspan, and constructorsIn the std::string_views: operator[], front, back, remove_prefix, remove_suffixIn all sequence containers (e.g., std::vector, std::array): operator[], front, back, pop_front, pop_backIn the std::strings: operator[], front, back, pop_backIn the multidimensional std::mdspan: operator[], and constructorsIn std::bitset: operator[]In std::valarray: operator[]In std::optional: operator->, operator*In std::expected: operator->, operator*, errorAnd that’s just a start, that has already made a real impact on hardening production code including on popular platforms.
Importantly, user code gets this benefit just by building with a hardened C++26 standard library — without any code changes. If you’ve seen any of my recent talks, you know this is close to my heart… see especially
this short clip in my code::dive 2024 talk about why C++26 removing undefined behavior for uninitialized locals is a model for adoptability and also this short clip in the Q&A about the societal value of improving C++.I think that Konstantin and Louis express that value proposition beautifully in their paper’s Motivation section, and I’ll quote most of their appeal here (emphasis original)… they “get it”:
“There has been significantly increased attention to safety and security in C++ over the last few years, as exemplified by the well-known White House report and numerous recent security-related proposals.
“While it is important to explore ways to make new code safer, we believe that the highest priority to deliver immediate real-world value should be to make existing code safer with minimal or no effort on behalf of users. Indeed, the amount of existing security-critical C++ code is so large that rewriting it or modifying it is both economically unviable and dangerous given the risk of introducing new issues.
“There have been a few proposals accepted recently that eliminate some cases of undefined behavior in the core language. The standard library also contains many instances of undefined behavior, some of which is a direct source of security vulnerabilities; addressing those is often trivial, can be done with low overhead and almost no work on behalf of users.
“In fact, at the moment all three major library implementations have some notion of a hardened or debug mode. This clearly shows interest, both from users and from implementers, in having a safer mode for the standard library. However, we believe these efforts would be vastly more useful if they were standardized and provided portable, cross-platform guarantees to users; as it stands, implementations differ in levels of coverage, performance guarantees and ways to enable the safer mode.
“Finally, leaving security of the library to be a pure vendor extension fails to position ISO C++ as providing a credible solution for code bases with formal security requirements. We believe that formally requiring the basic safety guarantees that most implementations already provide in one way or another could make a significant difference from the point of view of anyone writing or following safety and security coding standards and guidelines.”
In the next section, they demonstrate that this isn’t some theoretical improvement — it’s an improvement that is standardizing what is already shipping and significantly hardening existing C++ code today (emphasis added):
“All three major implementations provide vendor-specific ways of enabling library assertions as proposed in this paper, today.
We have experience deploying hardening on Apple platforms in several existing codebases. Google recently published an article where they describe their experience with deploying this very technology to hundreds of millions of lines of code. They reported a performance impact as low as 0.3% and finding over 1000 bugs, including security-critical ones. Google Andromeda published an article ~1 year ago about their successful experience enabling hardening. The libc++ maintainers have received numerous informal reports of hardening being turned on and helping find bugs in codebases.Overall, standard library hardening has been a huge success, in fact we never expected so much success. The reception has been overwhelmingly positive and while the quality of implementation will never be perfect, we are working hard to expand the scope of hardening in libc++, to improve its performance and the user experience.
This further demonstrates that not only is C++ making serious progress to improve, but that many of the language safety and software security improvements are already shipping without waiting for standardization. Standardization is still important, of course, because it makes these improvements available portably, with portable guarantees for C++ code on all platforms.
More things adopted for C++26: Core language changes/featuresNote: These links are to the most recent public version of each paper. If a paper was tweaked at the meeting before being approved, the link tracks and will automatically find the updated version as soon as it’s uploaded to the public site.
In addition to fixing a list of defect reports, the core language adopted 8 papers, including contracts (above) and the following…
P2786R13 “Trivial relocatability for C++26” by Alisdair Meredith, Mungo Gill, Joshua Berne, Corentin Jabot, Pablo Halpern, and Lori Hughes adds stronger support for optimizing the copying of memcpy-able types in the C++ language. This removes a source of “undefined behavior” that many container libraries rely on because it happens to be useful and probably-benign, and not only guarantees it is well-defined but also makes the optimizations more widely available for more types. Thank you, Alisdair and your collaborators, and thanks also to the authors of other trivial-relocation proposals that were not adopted! All of the input has made the result better, and we appreciate all the continued feedback.
P1967R14 “#embed – a scannable, tooling-friendly binary resource inclusion mechanism” by JeanHeyd Meneide enables “#include for binary data” — a portable way to pull binary data into a program without external tools and build system support. The introduction is clear and crisp:
“For well over 40 years, people have been trying to plant data into executables for varying reasons. Whether it is to provide a base image with which to flash hardware in a hard reset, icons that get packaged with an application, or scripts that are intrinsically tied to the program at compilation time, there has always been a strong need to couple and ship binary data with an application.
“Neither C nor C++ makes this easy for users to do, resulting in many individuals reaching for utilities such as xxd, writing python scripts, or engaging in highly platform-specific linker calls to set up extern variables pointing at their data. Each of these approaches come with benefits and drawbacks. For example, while working with the linker directly allows injection of very large amounts of data (5 MB and upwards), it does not allow accessing that data at any other point except runtime. Conversely, doing all of these things portably across systems and additionally maintaining the dependencies of all these resources and files in build systems both like and unlike make is a tedious task.
“Thusly, we propose a new preprocessor directive whose sole purpose is to be #include, but for binary data: #embed.”
Note that this feature has already been approved for inclusion in the next revision of C as well. See the proposal paper, especially sections 3.3 and 4.1, for more delightful background and design alternative discussion.
P2841R7 “Concept and variable-template template-parameters” by Corentin Jabot, Gašper Ažman, James Touton, and Hubert Tong adds the ability of passing concepts and variable templates as template parameters. Thank you, Corentin and your coauthors!
More things adopted for C++26: Standard library changes/featuresIn addition to fixing a list of defect reports, the standard library adopted 15 papers, including the following…
P0447R28 “Introduction of std::hive to the standard library” by Matthew Bentley is a major library addition that formalizes a widely-used high-performance data structure. From the paper’s overview:
“Hive is a formalisation, extension and optimization of what is typically known as a ‘bucket array’ or ‘object pool’ container in game programming circles. Thanks to all the people who’ve come forward in support of the paper over the years, I know that similar structures exist in various incarnations across many fields including high-performance computing, high performance trading, 3D simulation, physics simulation, robotics, server/client application and particle simulation fields (see this google groups discussion , the hive supporting paper #1 and appendix links to prior art ).
“The concept of a bucket array is: you have multiple memory blocks of elements, and a boolean token for each element which denotes whether or not that element is ‘active’ or ‘erased’ – commonly known as a skipfield. If it is ‘erased’, it is skipped over during iteration. When all elements in a block are erased, the block is removed, so that iteration does not lose performance by having to skip empty blocks. If an insertion occurs when all the blocks are full, a new memory block is allocated.
“The advantages of this structure are as follows: because a skipfield is used, no reallocation of elements is necessary upon erasure. Because the structure uses multiple memory blocks, insertions to a full container also do not trigger reallocations. This means that element memory locations stay stable and iterators stay valid regardless of erasure/insertion. This is highly desirable, for example, in game programming because there are usually multiple elements in different containers which need to reference each other during gameplay, and elements are being inserted or erased in real time. The only non-associative standard library container which also has this feature is std::list, but it is undesirable for performance and memory-usage reasons. This does not stop it being used in many open-source projects due to this feature and its splice operations.
“Problematic aspects of a typical bucket array are that they tend to have a fixed memory block size, tend to not re-use memory locations from erased elements, and utilize a boolean skipfield. The fixed block size (as opposed to block sizes with a growth factor) and lack of erased-element re-use leads to far more allocations/deallocations than is necessary, and creates memory waste when memory blocks have many erased elements but are not entirely empty. Given that allocation is a costly operation in most operating systems, this becomes important in performance-critical environments. The boolean skipfield makes iteration time complexity at worst O(n) in capacity(), as there is no way of knowing ahead of time how many erased elements occur between any two non-erased elements. This can create variable latency during iteration. It also requires branching code for each skipfield node, which may cause performance issues on processors with deep pipelines and poor branch-prediction failure performance.
“A hive uses a non-boolean method for skipping erased elements, which allows for more-predictable iteration performance than a bucket array and O(1) iteration time complexity; the latter of which means it meets the C++ standard requirements for iterators, which a boolean method doesn’t. It has an (optional – on by default) growth factor for memory blocks and reuses erased element locations upon insertion, which leads to fewer allocations/reallocations. Because it reuses erased element memory space, the exact location of insertion is undefined. Insertion is therefore considered unordered, but the container is sortable. Lastly, because there is no way of predicting in advance where erasures (‘skips’) may occur between non-erased elements, an O(1) time complexity [ ] operator is not possible and thereby the container is bidirectional but not random-access.”
Continuing the “making more things constexpr (and consteval)” drumbeat that allows more and more of the full C++ language and standard library be usable in constexpr code, we approved a set of constexpr extensions:
P3372R3 “constexpr containers and adaptors” by Hana Dusíková makes all containers and adapters constexpr (except for the new std::hive, above). P3378R2 “constexpr exception types” by Hana Dusíková makes all exception types used with constexpr code be constexpr too.Thanks, Hana! These are just the latest of a continued stream of Hana’s papers for constexpr-ing the C++ world; much appreciated — děkuju and arigato!
You may recall that at our last meeting we merged std::simd by Matthias Kretz for high-throughput parallel/vector programming into draft C++26. On Saturday we approved a set of further extensions and refinements, including:
P3441R2 “Rename simd_split to simd_chunk” by Daniel Towner and Ruslan Arutyunyan not only does what it says on the tin, but also adds new convenience overloads. P2663R7 “Interleaved complex values support in std::simd” by Daniel Towner and Ruslan Arutyunyan adds interleaved complex values support. P2933R4 “Extend header function with overloads for std::simd” by (you guessed it!) Daniel Towner and Ruslan Arutyunyan.Not to be outdone, P2976R1 “Freestanding library: algorithm, numeric, and random” by Ben Craig continues Ben’s march toward making a huge amount of C++ available on freestanding implementations. Thanks, Ben!
Last but not least, P3019R14 “indirect and polymorphic: Vocabulary types for composite class design” by Jonathan Coe, Antony Peacock, and Sean Parent adds value-semantic types for polymorphic objects to the standard library. This makes polymorphic types much easier to treat as values in value-like algorithms and use cases. Thanks very much, Jonathan and Antony and Sean!
What’s nextThank you to all the experts who worked all week in all the subgroups to achieve so much this week!
Our next meeting will be this June in Sofia, Bulgaria hosted by Chaos Group and C++ Alliance.
Thank you again to the over 200 experts who attended on-site and on-line at this week’s meeting, and the many more who participate in standardization through their national bodies!
But we’re not slowing down… in case you think C++“26” sounds very far away, it sure isn’t… we’re only one meeting away before the C++26 freeze in June, and even before that compilers are already aggressively implementing C++26, with GCC and Clang having already implemented about two-thirds of C++26’s language features adopted so far! C++ is a living language and moving fast. Thank you again to everyone reading this for your interest and support for C++ and its standardization.
January 16, 2025
code::dive 2024 interview video posted
After my code::dive talk in November, the organizers also recorded an extra 9-minute interview that covered these questions:
What role do you think AI will play in shaping programming languages?Do you have any rituals or routines before going on stage?What do you find most exciting about C++?What advice would you give to the code::dive community?Here it is…
New U.S. executive order on cybersecurity
The Biden administration just issued another executive order (EO) on hardening U.S. cybersecurity. This is all great stuff. (*) (**)
A lot of this EO is repeating the same things I urged in my essay nearly a year ago, “C++ safety — in context”… here’s a cut-and-paste of my “Call(s) to action” conclusion section I published back then, and I think you’ll see a heavy overlap with this week’s new EO…
Call(s) to actionAs an industry generally, we must make a major improvement in programming language memory safety — and we will.
In C++ specifically, we should first target the four key safety categories that are our perennial empirical attack points (type, bounds, initialization, and lifetime safety), and drive vulnerabilities in these four areas down to the noise for new/updated C++ code — and we can.
But we must also recognize that programming language safety is not a silver bullet to achieve cybersecurity and software safety. It’s one battle (not even the biggest) in a long war: Whenever we harden one part of our systems and make that more expensive to attack, attackers always switch to the next slowest animal in the herd. Many of 2023’s worst data breaches did not involve malware, but were caused by inadequately stored credentials (e.g., Kubernetes Secrets on public GitHub repos), misconfigured servers (e.g., DarkBeam, Kid Security), lack of testing, supply chain vulnerabilities, social engineering, and other problems that are independent of programming languages. Apple’s white paper about 2023’s rise in cybercrime emphasizes improving the handling, not of program code, but of the data: “it’s imperative that organizations consider limiting the amount of personal data they store in readable format while making a greater effort to protect the sensitive consumer data that they do store [including by using] end-to-end [E2E] encryption.”
No matter what programming language we use, security hygiene is essential:
Do use your language’s static analyzers and sanitizers. Never pretend using static analyzers and sanitizers is unnecessary “because I’m using a safe language.” If you’re using C++, Go, or Rust, then use those languages’ supported analyzers and sanitizers. If you’re a manager, don’t allow your product to be shipped without using these tools. (Again: This doesn’t mean running all sanitizers all the time; some sanitizers conflict and so can’t be used at the same time, some are expensive and so should be used periodically, and some should be run only in testing and never in production including because their presence can create new security vulnerabilities.)Do keep all your tools updated. Regular patching is not just for iOS and Windows, but also for your compilers, libraries, and IDEs.Do secure your software supply chain. Do use package management for library dependencies. Do track a software bill of materials for your projects.Don’t store secrets in code. (Or, for goodness’ sake, on GitHub!)Do configure your servers correctly, especially public Internet-facing ones. (Turn authentication on! Change the default password!)Do keep non-public data encrypted, both when at rest (on disk) and when in motion (ideally E2E… and oppose proposed legislation that tries to neuter E2E encryption with ‘backdoors only good guys will use’ because there’s no such thing).Do keep investing long-term in keeping your threat modeling current, so that you can stay adaptive as your adversaries keep trying different attack methods.We need to improve software security and software safety across the industry, especially by improving programming language safety in C and C++, and in C++ a 98% improvement in the four most common problem areas is achievable in the medium term. But if we focus on programming language safety alone, we may find ourselves fighting yesterday’s war and missing larger past and future security dangers that affect software written in any language.
Sadly, there are too many bad actors. For the foreseeable future, our software and data will continue to be under attack, written in any language and stored anywhere. But we can defend our programs and systems, and we will.
(*) My main disappointment is that some of the provisions have deadlines that are too far away. Specifically: Why would it take until 2030 to migrate to TLS 1.3? It’s not just more secure, it’s also faster and has been published for seven years already… maybe I’m just not aware enough of TLS 1.3 adoptability issues though, as I’m not a TLS expert.
(**) Here in the United States, we’ll have to see whether the incoming administration will continue this EO, or amend/replace/countermand it. In the United States, that’s a drawback of using an EO compared to passing an actual law with Congressional approval… an EO is “quick” because the President can issue it without getting legislative approval (for things that are in the Presidential remit), but for the same reason an EO also isn’t “durable” or guaranteed to outlive its administration. Because the next President can just order something different, an EO’s default shelf life is just 1-4 years.
So far, all the major U.S. cybersecurity EOs that could affect C++ have been issued since 2021, which means so far they have all come from one President… and so we’re all going to learn a lot this year, one way or another, about their permanence. (In both the U.S. and the E.U., actual laws are also in progress to shift software liability from consumer to software producers, and those will have real teeth. But here we’re talking about the U.S. EOs from 2021 to date.)
That said, what I see in these EOs is common sense pragmatism that’s forcing the software industry to eat our vegetables, so I’m cautiously optimistic that we’ll continue to maintain something like these EOs and build on them further as we continue to work hard to secure the infrastructure that our comfortable free lifestyle (and, possibly someday, our lives) depends on. This isn’t about whether we love a given programming language, it’s about how we can achieve the greatest hardening at the greatest possible scale for our civilization’s infrastructure, and for those of us whose remit includes the C++ language that means doing everything we can to harden as much of the existing C and C++ code out there as possible — all the programmers in the world can only write so much new/rewritten code every year, and for us in C++ by far the maximum contribution we can make to overall security issues related to programming languages (i.e., the subset of security issues that fall into our remit) is to find ways to improve existing C and C++ code with no manual source code changes — that won’t always be possible, but where it’s possible it will maximize our effectiveness in improving security at enormous scale. See also this 2-minute answer I gave in post-talk Q&A in Poland two months ago.
January 7, 2025
Speaking at University of Waterloo on January 15
Next week, on January 15, I’ll be speaking at the University of Waterloo, my alma mater. There’ll be a tech talk on key developments in C++ and why I think the language’s future over the next decade will be exciting, with lots of time allocated to a “fireside chat / interview” session for Q&A. The session is hosted by Waterloo’s Women in Computer Science (WiCS) group, and dinner and swag by Citadel Securities, where I work.
This talk is open to Waterloo students only (registration required). The organizers are arranging an option to watch remotely for the half of you who are away from campus on your co-op work terms right now — I vividly remember those! Co-op is a great experience.
I look forward to meeting many current students next week, and comparing notes about co-op work terms, pink ties (I still have mine) and MathSoc and C&D food (if Math is your faculty), WATSFIC, and “Water∞loo” jokes (I realize doing this in January is tempting the weather/travel gods, but I do know how to drive in snow…).
January 2, 2025
Speaking at New York C++ meetup on January 13
Less than two weeks from now, on January 13 I’ll be speaking at the New York C++ meetup in Midtown East (Clinton Hall at 230 E 51st Street). I’ll be giving a condensed update of my recent “Peering forward: C++’s next decade” talk, so that there’ll be plenty of time for Q&A — please have your questions ready about all the cool things happening right now in the ISO C++ world.
The meetup is sponsored by Citadel Securities, where I work. Food and drink will be served! Registration is free, but preregistration RSVP is required so please use the form at the link about to reserve your spot. A waitlist is available if space runs out.
I hope to see many of you there!
Herb Sutter's Blog
- Herb Sutter's profile
- 32 followers
