Trip report: Summer ISO C++ standards meeting (Varna, Bulgaria)

Minutes ago, the ISO C++ committee finished its meeting in-person in Varna, Bulgaria and online via Zoom, where we formally began adopting features into C++26.

Our hosts, VMware and Chaos, arranged for high-quality facilities for our six-day meeting from Monday through Saturday. We had nearly 180 attendees, about two-thirds in-person and the others remote via Zoom, formally representing 20 nations. Also, at each meeting we regularly have new attendees who have never attended before, and this time there were 17 new first-time attendees, mostly in-person; to all of them, once again welcome!

The committee currently has 23 active subgroups, most 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 and/or evening, depending on their wortpkloads. You can find a brief summary of ISO procedures here.

This week’s meeting: Starting C++26

ISO C++ is on a three-year development cycle, which includes a “feature freeze” about one year before we ship and publish that edition of the standard. For example, the feature freeze for C++23 was in early 2022.

But this doesn’t mean we only have two years’ worth of development time in the cycle and the third year is bug fixes and red tape. Instead, the subgroups are a three-stage pipeline and continue concurrently working on new feature development all the time, and the feature freezes are just the checkpoints where we pause loading new features into this particular train. So for the past year, as the subgroups finished work on fit-and-finish for the C++23 features, they also increasingly worked on C++26 features.

That showed this week, as we adopted the first 40 proposed change papers for C++26, many of which had been ready for a couple of meetings and were just waiting for the C++26 train to open for loading to be adopted. Of those 40 change papers, two were “apply the resolutions for all Ready issues” papers that applied a bunch of generally-minor changes. The other 38 were individual changes, everything from bug fixes to new features like hazard pointers and RCU.

Here are some of the highlights…

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

The core language adopted 11 papers, including the following. Taking them in paper number order, which is roughly the order in which work started on the paper…

P2169 “A nice placeholder with no name” by Corentin Jabot and Michael Park officially adds support for the _ wildcard in C++26. Thanks to the authors for all their research and evidence for how it could be done in a backward-compatible way! Here are some examples that will now be legal as compilers start to support draft-C++26 syntax:

std::lock_guard _(mutex);

auto [x, y, _] = f();

inspect(foo) { _ => bar; };

Some compiler needs to implement -Wunderbar.

The palindromic P2552 “On the ignorability of standard attributes” by Timur Doumler sets forth the Three Laws of Robotics… er, I mean, the Three Rules of Ignorability for standard attributes. The Three Rules are a language design guideline for all current and future standard attributes going forward… see the paper for the full rules, but my informal summary is:

  • [Already in C++23] Rule 1. Standard attributes must be parseable (i.e., can’t just contain random nonsense).
  • [Already in C++23] Rule 2. Removing a standard attribute can’t change the program’s meaning: It can reduce the program’s possible legal behaviors, but it can’t invent new behaviors.
  • [New] Rule 3. Feature test macros shouldn’t pretend to support an attribute unless the implementation actually implements the attribute’s optional semantics (i.e., doesn’t just parse it but then ignore it).

P2558 “Add @, $, and ` to the basic character set” by Steve Downey is not a paper whose name was redacted for cussing; it’s a language extension paper that follows in C’s footsteps, and allows these characters to be used in valid C++ programs, and possibly in future C++ language evolution.

P2621 “UB? In my lexer?” by Corentin Jabot removes the possibility that just tokenizing C++ code can be a source of undefined behavior in a C++ compiler itself. (Did you know it could be UB? Now it can’t.) Note however that this does not remove all possible UB during compilation; future papers may address more of those compile-time UB sources.

P2738 “constexpr cast from void*: towards constexpr type-erasure” by Corentin Jabot and David Ledger takes another step toward powerful compile-time libraries, including enabling std::format to potentially support constexpr compile-time string formatting. Speaking of which…

P2741 “User-generated static_assert messages” by Corentin Jabot lets compile-time static_assert accept stringlike messages that are not string literals. For example, the popular {fmt} library (but not yet std::format, but see above!) supports constexpr string formatting, and so this code would work in C++26:

static_assert(sizeof(S) == 1, fmt::format("Unexpected sizeof: expected 1, got {}", sizeof(S)));

Together with P2738, an implementation of std::format that uses both of the above features would now be able to used in a static_assert.

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

The standard library adopted 28 papers, including the following. Starting again with the lowest paper number…

This first one gets the award for “being worked on the longest” (just look at the paper number, and the R revision number): P0792R14, “function_ref: A type-erased callable reference” by Vittorio Romeo, Zhihao Yuan, and Jarrad Waterloo adds function_ref<R(Args...)> as a vocabulary type with reference semantics for passing callable entities to the standard library.

P1383 “More constexpr for <cmath> and <complex>” by Oliver J. Rosten adds constexpr to over 100 more standard library functions. The march toward making increasing swathes of the standard library usable at compile time continues… Jason Turner is out there somewhere saying “Moar Constexpr!” and “constexpr all the things!”

Then, still in paper number order, we get to the “Freestanding group”:

P2510 “Formatting pointers” by Mark de Wever allows nice formatting of pointer values without incanting reinterpret_cast to an integer type first. For example, this will now work: format("{:P}", ptr);

P2530 “Hazard pointers for C++26” by Maged M. Michael, Michael Wong, Paul McKenney, Andrew Hunter, Daisy S. Hollman, JF Bastien, Hans Boehm, David Goldblatt, Frank Birbacher, and Mathias Stearn adds a subset of the Concurrency TS2 hazard pointer feature to add hazard pointer-based deferred cleanup to C++26.

P2545 “Read-Copy-Update (RCU)” by Paul McKenney, Michael Wong, Maged M. Michael, Andrew Hunter, Daisy Hollman, JF Bastien, Hans Boehm, David Goldblatt, Frank Birbacher, Erik Rigtorp, Tomasz Kamiński, Olivier Giroux, David Vernet, and Timur Doumler as another complementary way to do deferred cleanup in C++26.

P2548 “copyable_function” by Michael Hava adds a copyable replacement for std::function, modeled on move_only_function.

P2562 “constexpr stable sorting” by Oliver J. Rosten enables compile-time use of the standard library’s stable sorts (stable_sort, stable_partition, inplace_merge, and the ranges:: versions). Jason Turner is probably saying “Moar!”…

P2641 “Checking if a union alternative is active” by Barry Revzin and Daveed Vandevoorde introduces the consteval bool is_within_lifetime(const T* p) noexcept function, which works in certain compile-time contexts to find out whether p is a pointer to an object that is within its lifetime — such as checking the active member of a union, but during development the feature was made even more generally useful than just that one use case. (This is technically a core language feature, but it’s in one of the “magic std:: features that look like library functions but are actually implemented by the compiler” section of the standard, in this case the metaprogramming clause.)

P2757 “Type-checking format args” by Barry Revzin enables even more compile-time checking for std::format format strings.

Those are just 12 of the adopted papers as highlights… there were 16 more papers adopted that also apply more extensions and fixes for the C++26 standard library.

Other progress

We also adopted the C++26 schedule for our next three-year cycle. It’s the same as the schedule for C++23 but just with three years added everywhere, just as the C++23 schedule was in turn the same as the schedule for C++20 plus three years.

The language evolution subgroup (EWG) saw 30 presentations for papers during the week, mostly proposals targeting C++26, including fine-tuning for some of the above that made it into C++26 at this meeting.

The standard library evolution subgroup (LEWG) focused on advancing “big” papers in the queue that really benefit from face-to-face meetings. Notably, there is now design consensus on P1928 SIMD, P0876 Fibers, and P0843 inplace_vector, and those papers have been forwarded to the library wording specification subgroup (LWG) and may come up for adoption into C++26 at our next meeting in November. Additional progress was made on P0447 hive, P0260 Concurrent Queues, P1030 path_view, and P2781 constexpr_v.

The library wording specification subgroup (LWG) is now caught up with their backlog, and spent a lot of time iterating on the std::execution and sub_mdspan proposals (the latter was adopted this week).

The contracts subgroup made further progress on refining contract semantics targeting C++26, including to get consensus on removing build modes and having a contract violation handling API.

The concurrency and parallelism subgroup are still on track to move forward with std::execution and SIMD parallelism for C++26, which in the words of the subgroup chair will make C++26 a huge release for the concurrency and parallelism group.

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 two meetings will be in Kona, HI, USA in November hosted by WorldQuant and the Standard C++ Foundation, and Tokyo, Japan in March hosted by Woven by Toyota.

Wrapping up

Thank you again to the nearly 180 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… we’ll continue to have subgroup Zoom meetings, and then in less than five months from now we’ll be meeting again in person + Zoom to continue adding features to C++26. Thank you again to everyone reading this for your interest and support for C++ and its standardization.