Trip report: November 2024 ISO C++ standards meeting (Wrocław, Poland)

On Saturday, the ISO C++ committee completed the third-last design meeting of C++26, held in Wrocław, Poland. There are just two meetings left before the C++26 feature freeze in June 2025, and C++26 is on track to be completed two more meetings after that in early 2026. Implementations are closely tracking draft C++26; GCC and … Continue reading Trip report: November 2024 ISO C++ standards meeting (Wrocław, Poland) →

Jan 14, 2025 - 10:30
 0
Trip report: November 2024 ISO C++ standards meeting (Wrocław, Poland)

On Saturday, the ISO C++ committee completed the third-last design meeting of C++26, held in Wrocław, Poland. There are just two meetings left before the C++26 feature freeze in June 2025, and C++26 is on track to be completed two more meetings after that in early 2026. Implementations are closely tracking draft C++26; GCC and Clang already support about two-thirds of C++26 features right now.

Our host, Nokia, arranged for high-quality facilities for our six-day meeting from Monday through Saturday. We had over 220 attendees, about two-thirds in-person and the others remote via Zoom, formally representing 31 nations. At each meeting we regularly have new attendees who have never attended before, and this time there were 37 new first-time attendees, mostly in-person. To all of them, once again welcome!

The committee currently has 23 active subgroups, 15 of which met in 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 two combined informational evening sessions to inform the committee broadly about progress on key topics: one on contracts, the other on relocatability. You can find a brief summary of ISO procedures here.

This 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:

  • P2996 Reflection is in specification wording review aiming for C++26.
  • P2900 Contracts continues to have a chance of being in C++26 – probably more time was spent on contracts this week in various subgroups than on any other feature.
  • P3081 Safety Profiles and P3471R0 Standard library hardening made progress into the Evolution group and have a chance of being an initial set of profiles for C++26.

Adopted for C++26: Core language changes/features

Note: 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 the following…

P2686R5 “constexpr structured bindings and references to constexpr variables” by Corentin Jabot and Brian Bi. The paper itself contains a great explanation, pasting from page 8:

You can now declare structured bindings constexpr. Because structured bindings behave like references, constexpr structured bindings are subject to similar restrictions as constexpr references, and supporting this feature required relaxing the previous rule that a constexpr reference must bind to a variable with static storage duration. Now, constexpr references and structured bindings may also bind to a variable with automatic storage duration, but only when that variable has an address that is constant relative to the stack frame in which the reference or structured binding lives.

Thanks, Corentin and Brian!

P3068R6 “Allowing exception throwing in constant evaluation” by Hana Dusíková continues the very-welcome and quite-inexorable march toward allowing more and more of C++ to run at compile time. “Compile-time C++, now with exceptions so you can use normal C++ without rewriting your error handling to return codes/std::expecteds!” is the nutshell synopsis. Thank you, Hana!

Adopted for C++26: Standard library changes/features

In addition to fixing a list of defect reports, the standard library adopted 19 papers, including the following…

P3370R1 “Add new library headers from C23” by Jens Maurer is an example of how C++ continues trying to align with C. As the paper states: “C23 added the and headers. This paper [adds] these headers to C++ to increase the subset of code that compiles with C and C++. […] Type-generic macros and type-generic functions do not exist in C++, but function templates can provide the same call interface. Thus, the use of the former in C is replaced by the latter in C++.” Thank you Jens!

(For those who don’t know of Jens, he’s one of the committee’s unsung Energizer Bunnies: He chairs the Core language specification working group all week long at every meeting, he’s the key logistics person who makes every meeting run smoothly from organizing room layouts and A/V to break drinks/snacks, he organizes every meeting’s space allocations for all the subgroups and evening sessions, and after all that he clearly still has time left over to write standard library papers too! We don’t know how he does it all, but the unconfirmed rumor is that there’s a secret clone involved; investigation is still pending.)

Because Hana (already mentioned above) can’t stop adding to constexpr, P3309R3 “constexpr atomic and atomic_ref by Hana Dusíková does what it says on the tin. If you’re wondering whether this is important (after all, we don’t support threads in constexpr code… yet… and usually atomic is about concurrency), the paper explains:

This paper […] allows implementing other types (std::shared_ptr, persistent data structures with atomic pointers) and algorithms (thread safe data-processing, like scanning data with atomic counter) with just sprinkling constexpr to their specification.

So perhaps a good synopsis would be: “removing the last excuse not to make shared_ptr available in constexpr code!” Thanks, Hana!

P1928R15 “std::simd — merge data-parallel types from the Parallelism TS 2” by Matthias Kretz adopts the data-parallel basic_simd types from the TS into C++26 as std::basic_simd. Two notes: (1) The “changes since the TS” section has a “constexpr everything” section, because that’s just how we roll in WG21 these days (cf: Hana’s papers above). (2) Note the “R” revision number, which indicates the 15 revisions of this proposal that were needed to get it to land — thank you for the determined hard work, Matthias, and once again congratulations from us all: When this proposal was adopted, a sustained round of loud applause filled the room!

Last but not least, P3325R5 “A utility for creating execution environments” by Eric Niebler builds on the huge new std::execution concurrency and parallelism library that was adopted at our previous meeting this summer (see my summer 2024 trip report) to additionally make it easier to create and merge loci of execution. Definitely read section 4 of the paper for a full description of the motivation and use cases. Thanks very much, Eric!

Other progress

All subgroups continued progress, more of which will no doubt be covered in other trip reports. Here are a few more highlights…

SG1 (Concurrency): Concurrent queues “might” make C++26, and this is one of the most compelling demonstrations of the “sender/receiver” design pattern in the new std::execution that was adopted at our previous meeting. Concurrent queues would also be (finally) the first concurrent data structure in the standard. Also, although SG1 has been trying to fix/specify memory_order_consume since C++11, this has not succeeded, so the feature has now been removed.

SG7 (Compile-Time Programming): Made progress on several papers. Perhaps the most visible decision was to decide on a reflection syntax, ^^, which apparently some people are lobbying hard to call the “unibrow operator.”

SG15 (Tooling): Progressed work on the Ecosystem IS (International Standard), which achieved the milestone of being approved to be forwarded to the main design subgroups.

SG20 (Education): Progressed work on creating C++ teaching guidelines about topics that should be taught in C++ educational settings. Encouraged paper authors and chairs to send papers to SG20 for teachability feedback.

SG21 (Contracts): Spent Wednesday in the Core working group (instead of meeting separately) because EWG sent contracts to Core aiming for C++26, so the contracts experts went to Core to help with wording review. Continued work on trying to increase consensus on some design details.

SG23 (Safety and Security): Approved several papers to progress, including to reduce undefined behavior in the language and specifically time travel optimizations, and to send an initial set of core safety profiles to EWG aiming for C++26. The proposal P3390 “Safe C++” by Sean Baxter was seen and received support as a direction that can be pursued in addition to and complementary with Profiles, where Profiles are useful to define subsets of current C++ and its features and reducing its undefined behaviors to reduce unsafety in current C++, and proposals like Safe C++ can be useful to propose new extensions for an expanded C++ to try to achieve larger/stronger safety guarantees not possible in just a subset/constrained C++. The SG23 vote on which to prioritize was 19:11:6:9 for Profiles:Both:Neutral:SafeC++.

EWG (Language Evolution Working Group) forwarded contracts aiming for C++26, understanding however that there are still a few unresolved contentious design points; the groups are working on increasing consensus between now and the next meeting. Adopted the ^^ operator for reflection. Pattern matching is still trying to make C++26. Three safety papers progressed: P3081 core safety profiles (see below; for detailed telecon review between meetings and aiming for approval at our next meeting), P3471R0 “Standard library hardening” by Konstantin Varlamov and Louis Dionne which passed unanimously (no one even neutral!), and P2719 “Type-aware allocation and deallocation functions” by Louis Dionne and Oliver Hunt which offers safety mitigation building blocks. The group also approved trivial relocatability for C++26.

LEWG (Library Evolution Working Group) reviewed 30 papers this week. LEWG is specifically prioritizing its time on these topics as papers are available: relocatability, parallel algorithms, concurrent queues, constexpr containers, safety profiles, and pattern matching.

Thank you to all the experts who worked all week in all the subgroups to achieve so much this week!

What’s next

Our next meeting will be in Hagenberg, Austria hosted by University of Applied Sciences Upper Austria, RISC Software GmbH, and Softwarepark Hagenberg.

Thank you again to the over 220 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!

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.




Coda: My papers at this meeting

My papers aren’t what’s most important, but since this is my trip report I should mention my papers.

I had eight papers at this meeting, of which seven were seen at the meeting and one will be seen in an upcoming telecon. Here they are in the rough order they were seen…

P3437R0 “Principles: Reflection and generation of source code”

On Monday, in the SG7 (Compile-Time Programming) subgroup I presented P3437R0 “Principles: Reflection and generation of source code.”

In a nutshell, P3437 advocates for the principle that reflection and generation are primarily for automating reading and writing source code, the way a human programmer would do but so the human doesn’t have to do it by hand. I argue that this view implies that, at least by default:

  • reflecting a class (or other entity) in consteval compile-time code should be able to see everything a human could know from reading the source code of the class’s definition; and,
  • similarly, generating a class in consteval code should be able to write anything the human programmer could write (including things like adding specializations to std) and have the same language meaning as if the programmer wrote it by hand (including normal name lookup and access control).

Non-default modes might do more or different things, but I argued that “as if the human read/wrote the source code” should be the default semantics and get the “nice” syntax that C++ programmers would naturally expect unless they were doing something special.

The group agreed and approved the paper, 15:8:3 in favor:neutral:against.

P3439 “Chained comparisons: Safe, correct, efficient”

On Tuesday, I presented P3439 “Chained comparisons: Safe, correct, efficient” in the language evolution working group (EWG). This paper proposes that comparison chains like a <= b < c actually work. (I’ve already implemented this in cppfront.) Today, people try to write such code, and the standard says it’s required to compile but do the wrong thing, which is not great, and all major compilers will warn about it but then compile it anyway because they must. Adopting this proposal would fix real bugs, including security bugs, just by recompiling existing code. This change would also make the language simpler, because with this feature we could write a <= b && b < c as just a <= b < c. And that would also make the language slightly faster, by naturally avoiding multiple evaluation of middle terms like b.

This is the only part of my original paper P0515R0 “Consistent comparisons” (aka the operator spaceship <=> paper) that has not yet been adopted into the standard. It was rejected before the pandemic when Barry Revzin and I tried a second time to get it adopted, but I felt it was appropriate to bring it back now because there’s new urgency and new information. A few highlights from the paper:

Today, comparison chains like min <= index_expression < max are valid code that do the wrong thing; for example, 0 <= 100 < 10 means true < 10 which means true, certainly a bug. Yet that is exactly a natural bounds check; for indexes, such subscript chains’ current meaning is always a potentially exploitable out-of-bounds violation.

[P0893R1] reported that code searches performed by Barry Revzin with Nicolas Lesser and Titus Winters found:

  • Lots of instances of such bugs in the wild: in real-world code “of the assert(0 <= ratio <= 1.0); variety,” and “in questions on StackOverflow [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11].”
  • A few thousand instances over just a few code bases” (emphasis original) where programmers today write more-brittle and less-efficient long forms such as min <= index_expression && index_expression < max because they must, but with multiple evaluation of index_expression and with bugs because of having to write the boilerplate and sometimes getting it wrong.

See the paper for more new information that warrants considering this anew.

The group voted 30:2:2 in favor:neutral:against for me to bring this back with standardese wording to the February meeting, and if things go well there it might make C++26.

Next: Three safety/security proposals for me at this meeting

Although the chained-comparisons proposal had a safety and security aspect, I don’t consider it principally a “safety proposal.” However, I did present three actual safety and security proposals at this meeting, and here they are… (Note: There were other such proposals by others too, not just by me! And I’m excited about them too. These are just my three…)

Of the four main language safety categories we have to improve (type, bounds, initialization, and lifetime), the first three are easier and are the focus of P3436 and P3081. Lifetime is the hardest to improve in C++, and requires more effort, in my proposal’s case writing a static analysis rule engine; but I think major improvement is possible without heavy annotation of existing code, and this is the subject of P3465 (promoting P1179).

Safety #1 of 3: P3436R0 “Removing safety-related undefined behavior by default”

On Wednesday morning in SG23 (Safety and Security), I presented P3436R0 “Removing safety-related undefined behavior (UB) by default.” This would be a pretty big deal… as I mentioned in the presentation, I firmly believe that most observers of C++, even friendly ones, do not expect us to be able to “do something significant” about UB in C++. UB is after all a fundamental part of C++, right? … Right?

My conjecture is “no it isn’t, and the point of this paper is easy to summarize:

  • C++ already bans undefined behavior in a huge subset of the language: constexpr evaluation. A lot of people do not realize that, yes, we already did that… we already snuck a lot of safety into the language while no one was paying particular attention. Those who say UB is endemic throughout C++ have already started to fall behind the times, since we added and then gradually expanded constexpr.
  • Let’s enumerate each such case of UB already prevented in constexpr evaluation, and prevent it in normal execution too: either always (if it’s cheap and easy, as we just did with uninitialized local variables), or else under a Profile (so any overhead has an easy way to opt-in/opt-out when you do/don’t want the safety).

I think most people don’t expect that C++ could make a major dent in undefined behavior and still be true to C++. But P3436 makes the bold conjecture that maybe we can not only make a dent, but actually eliminate UB in C++ by default when safety Profiles are enabled, by combining (a) that we already do it in constexpr code, with (b) that we plan to have Profiles as a tool to opt in/out of safety modes that require source changes or execution overheads.

The group agreed and voted unanimously 25:3:0 in favor:neutral:against.

Important reality check here: This is the start, not the end… this doesn’t mean the proposal is done, it means the group said “we like the idea, now go do the hard work of actually listing all the UB cases and how you propose to handle each one and writing up standard specification wording for all that.” Most “encouragement” polls in the committee actually mean “yes please go do more work.” (This takes a lot of getting used to for new participants.)

Safety #2 of 3: P3465R0 “Pursue P1179 as a Lifetime TS”

On Wednesday after lunch in SG23 (Safety and Security), I made the first-ever presentation in WG21 of the C++ Core Guidelines Lifetime safety static analysis profile, of which I’m the primary designer (with lots of expert help; big thanks again everyone listed in P1179!). This analysis catches many common lifetime dangling issues (not just for pointers, but for generalized Pointers including iterators and views), usually with little or no source annotation. This is a full portable “static analysis specification” which means a detailed spec of state and state transitions that an implementation should do in a function body, so that different implementations will give the same answers.

I first publicly presented this work, with live demos of the first prototype, in my CppCon 2015 talk (starting at 30:28). I then published the detailed specification on GitHub and cc’d/FYI’d ISO via the paper P1179 “Lifetime safety: Preventing common dangling” back in 2019, but at that point I was just giving the committee an FYI… I never asked to present it for adoption, in part because I wanted to gain more usage experience, and in part because at the time the committee did not yet have this kind of safety as a first-order priority.

Now, times have changed: Parts of this have now been implemented and shipped in Microsoft Visual Studio, JetBrains CLion, a Clang fork, and even a smidgen in Clang trunk I’m told. And safety/security is finally a first-order concern, so the current paper P3465R0 “Pursue P1179 as a Lifetime TS” points back to P1179 and suggests that the time is ripe to turn it into an ISO C++ Technical Specification. I proposed that we pursue turning this analysis specification into a Technical Specification (TS) separate from the standard in order to get one more round of WG21-endorsed experience before we cast it in stone as a lifetime Profile: While implementations have implemented a lot of the design, they haven’t yet implemented all of it, and I think making it a TS would show WG21 interest and spur them to complete their implementations so that we could validate the last few important parts too on large amounts of real-world code, and make any needed adjustments. If all goes well with that, I hope to propose it for the standard itself in the future.

The group voted 24:0:1 in favor:neutral:against to direct me to turn P1179 into a working paper for a Technical Specification. Fortunately, the specification of state and state transitions is already very concrete, so it’s already at approximately the same level of detail as normal C++ language specification wording.

Safety #3 of 3: P3081R0 “Core safety Profiles: Specification, adoptability, and impact”

My third safety/security paper was P3081R0 “Core safety Profiles: Specification, adoptability, and impact.” I presented it Wednesday afternoon in SG15 (Tooling), Thursday morning in SG23 (Safety and Security), and Friday morning in EWG (the main language evolution group), with a target of C++26.

This is a companion paper to my “C++ safety, in context” blog essay this spring; see that essay for the full motivation, context, and rationale. P3081 contains the concrete proposed semantics:

  • Proposes a concrete initial set of urgently needed enforced safety Profiles.
  • Described how a Profiles implementation can prioritize adoptability and safety improvement impact, especially to silently fix serious bugs in existing code by just recompiling the code (i.e., no manual code changes required) where possible, and making it easy to opt into broadly applicable safety profiles.

I tried to push the boundaries of what’s possible in C++ by suggesting we do something we’ve never done before in the ISO C++ standard: Have the Standard actually normatively (i.e., as a hard requirement) require implementations (usually compilers, and not third-party post-build tools) to offer safety-related “fixits” to automatically correct C++ code where the fix can be super reliable. We’ve never formally required anything like this before, but I felt it was important to try to push this boundary to raise the bar for all compilers because it’s so important for safety adoptability… yet I really wasn’t sure how this suggestion would fly (or get shot out of the sky, as boundary-pushing proposals tend to be).

The first presentation was on Wednesday after lunch to SG15 (Tooling) because the paper suggested this novelty of requiring C++ compilers to offer automatic fixits. The votes on two related polls were both unanimously 8:2:0 in favor:neutral:against. People in the room included tooling and compiler experts for GCC and Clang, and their main comment was (slightly paraphrased) ‘yeah, sure, this is 2024, our C++ compilers all already offer fixits, let’s require compilers to do it consistently.’ Whew.

The second presentation was on Thursday after breakfast to SG23 (Safety and Security), which has been encouraging work on Profiles but has not yet had any concrete proposal to forward to EWG, the main evolution working group. SG23 gave feedback, and then voted unanimously 23:1:0 in favor:neutral:against to forward P3081 to EWG specifically targeting C++26, including that Bjarne’s paper and this one should be merged to reflect the syntax decisions made earlier in the day based on Bjarne’s paper. This is the first Profiles proposal to be forwarded from SG23.

The third presentation was on Friday after breakfast to EWG, which voted 44:4:3 in favor:neutral:against to pursue this paper for C++26, and schedule teleconferences between now and February to go line-by-line through the paper in detail.

Disclaimer: Note this means we have to do a ton of work in the next few months, if it is to have a hope of actually making C++26.

P2392R3 “Pattern matching using is and as”

On Thursday in EWG, I presented P2392R3 “Pattern matching using is and as.” There are two main parts to this paper: is/as expressions to unify and simplify safe queries/casts, and inspect pattern matching that uses the is/as approach.

This time the results were quite mixed, with no consensus to encourage proceeding with my proposal: For the whole paper, EWG voted 19:6:22 in favor:neutral:against. For just the is/as portion, EWG voted 21:8:20 in favor:neutral:against. Clearly no consensus at all, never mind not strong encouragement, and the competing proposal from Michael Park got 33:6:10. But I’m not giving up P2392… I’ll try to incorporate the feedback heard in the room, and perhaps improve consensus at the next meeting or two.

P3466R0 “(Re)affirm design principles for future C++ evolution”

Finally, on Friday afternoon in EWG, I presented P3466 “(Re)affirm design principles for future C++ evolution.” Note: I presented the initial revision R0, and this link is to a draft revision R1 that incorporates the direction from the group (but my R1 edits are still being reviewed to make sure I applied EWG’s direction correctly).

The summary up front is:

C++ is a living language that continues to evolve. Especially with C++26 and compile-time programming, and new proposals for type and memory safety, we want to make sure C++ evolution remains as cohesive and consistent as possible so that (a) it’s “still C++” in that it hews to C++’s core principles, and (b) it’s delivering the highest quality value to make C++ code safer and simpler.

The Library Evolution WG has adopted written design principles to guide proposals and their discussion. This paper proposes that the Language Evolution WG also adopt written principles to guide new proposals and their discussion, and proposes the principles in this paper as a starting point.

EWG voted to turn this paper into a new Standing Document (which future papers can add to) to document EWG’s values: 29:22:2 in favor:neutral:against.

P0707R5 “Metaclass functions for generative C++”

The committee didn’t have time to consider all papers at the meeting, and my paper P0707R5 “Metaclass functions for generative C++” is one that got deferred to be considered at a between-meetings Zoom telecon over the winter.

That’s it for my papers this time… whew. More news next time, from Austria…

What's Your Reaction?

like

dislike

love

funny

angry

sad

wow