Table of Contents

Last week the ISO committee met in Varna to discuss some of the first batch of C++26 features. It’s an excellent occasion to shed some light on the latest status and interesting C++ proposals.

Let’s start!

By the way: This will be my first blog post with the #cpp26 tag!

Disclaimer: The views expressed in this article are my own and do not represent the opinion of the ISO C++ Committee.

Return to In-Person ISO Meetings  

With the pandemic largely behind us, we’re left adapting to a blend of virtual and in-person meetings. The ISO Committee held its first “post-pandemic” in-person meeting in Kona, HI, USA, in November 2022, followed by another one in Issaquah, USA, in February 2023. These meetings predominantly follow a hybrid format.

Both meetings served to complete the work on C++23!

Check out the report from Herb Sutter’s winter update:

C++23 “Pandemic Edition” is complete (Trip report: Winter ISO C++ standards meeting, Issaquah, WA, USA) – Sutter’s Mill

The Latest Varna Meeting  

Last week, from June 12th to the 16th, a meeting took place in Varna, Bulgaria. If I recall correctly, this meeting was initially planned for June 2020 but was postponed due to the pandemic. Thankfully, it seems the committee is now back to its regular international meeting schedule.

Approximately 180 attendees participated this time, with two-thirds in person and one-third joining online.

This meeting was the first to focus entirely on the C++26 standard! A new batch of features has already been accepted. We’ll delve into the current status of this standard in the following section.

You can find more information about the meeting in Herb’s latest article:

Trip report: Summer ISO C++ standards meeting (Varna, Bulgaria) – Sutter’s Mill

And have a look at Think-Cell’s report: Trip report: Summer ISO C++ Meeting in Varna, Bulgaria | think-cell

The Status of C++23  

Two ISO meetings - one in Kona in November and another in Issaquah in February - finalized the C++23 draft. The draft is ready and has been sent for final voting and editorial changes. We can anticipate the official ISO publication at the end of 2023.

See all of the C++23 features on the C++ Reference page:

Compiler support for C++23 @cppreference.com

The Status of C++26  

In Varna, the committee approved the first 40 proposed change papers for C++26, encompassing everything from bug fixes to new features like hazard pointers and RCU.

The overall plan for C++26 can be found in P0592: To boldly suggest an overall plan for C++26

Key objectives:

  • C++26 prioritizes on-time delivery while focusing on key feature sets - the standard is rolled out using a “train model” of releases. There’s a set deadline (typically a year in advance) that features must meet to be included in the standard.
  • High-priority items include Execution, further work on Ranges, and Reflection.
  • Contracts and Pattern Matching are in progress, but their inclusion in C++26 isn’t guaranteed.
  • Additional library support for Coroutines and Networking is also included.

As always, you can monitor their status on this comprehensive cppreference page:

Compiler support for C++26 @cppreference.com

Awesome papers  

Now, let’s explore some recent papers that caught my attention in H1

Here are the links for:

Let’s begin with a minor language feature:

P2169 “A Handy Placeholder with No Name”  

P2169, voted into C++26

Occasionally, we are more interested in their side effects than their names for variables such as locks, scope guards, or parts of structured bindings. In these situations, we can use the single underscore _, a convention in C and C++ for unused variables. It encapsulates the “I don’t care” sentiment that is suitable for placeholders.

[[maybe_unused]] auto [x, y, iDontCare] = f();

Can be re-written as:

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

Generally:

auto _ = foo(); // equivalent to 

Expands to:

[[maybe_unused]] auto _ = f();

P2621 “UB? In My Lexer?”  

P2621, voted into C++26

It appears that the following code:

int \\ // UB : universal character name across spliced lines
u\
0\
3\
9\
1 = 0;

// or:
// UB: unterminated string
const char * foo = "

Can generate UB in the Lexer! The paper proposes to address such holes, thereby ensuring a more robust compilation across different vendors.

P2530 “Hazard Pointers for C++26”  

P2530, voted into C++26

A hazard pointer is a type of single-thread-owned pointer used to protect dynamic objects from premature reclamation during concurrent operations. The owning thread sets the pointer to an object, signaling that it’s not yet safe for reclamation. Removed objects are retired to the hazard pointer library, which assumes the reclamation responsibility. The basic principle is that an object can only be reclaimed once it’s confirmed that no hazard pointers have been pointing to it since before its retirement. The method revolves around the interaction between protection and deferred reclamation.

Here’s a quote by Andrei Alexandrescu and Maged Michael:

Each reader thread owns a single-writer/multi-reader shared pointer called “hazard pointer.” When a reader thread assigns the address of a map to its hazard pointer, it is basically announcing to other threads (writers), “I am reading this map. You can replace it if you want, but don’t change its contents and certainly keep your deleteing hands off it.”

In summary:

  • A hazard pointer safeguards dynamic objects during concurrent operations.
  • Only the owning thread can set the pointer.
  • Removed objects are retired to the hazard pointer library.
  • An object can be reclaimed only after ensuring that no hazard pointers have been pointing to it since before its retirement.
  • The method centers on the concept of protection and deferred reclamation.

The reference implementation of hazard pointers, which includes a superset of the proposed interface, is in the Folly open-source library.

Find more information in Hazard Pointer Synchronous Reclamation Beyond Concurrency TS2 - Maged Michael - CppCon 2021 - YouTube

P0843 static_vector/inplace_vector  

P0843, voted into C++26

Update, thanks to comment from ben_craig : P0843 static_vector/inplace_vector hasn’t been voted into C++26 yet. The overall design has been approved, but the specification in the paper hasn’t been approved

This paper proposes a revamped boost::static_vector<T, Capacity> (see at boost), a dynamic yet compile-time capacity-fixed vector with embedded contiguous storage. The API is akin to std::vector<T, A>, offering constant-time insertion/removal at the end and O(size()) in other cases. The static_vector is beneficial when memory allocation is unfeasible or detrimental to performance, or in scenarios where objects with complex lifetimes need static-memory segment allocation. This proposal suggests implementing static_vector as a standalone type, with semantics and layout similar to std::vector. The move semantics follow the std::vector model, with constexpr support provided for certain type conditions. Exception safety follows the same pattern as std::vector. However, iterator invalidation guarantees differ slightly. The paper proposes a name change from static_vector to inplace_vector for clarity.

P1759 Native Handles and File Streams  

P1759, voted into C++26

The C++ proposal introduces native_handle_type as an alias to the file descriptor type used by a platform (e.g., int for POSIX, HANDLE for Windows). It also adds a member function .native_handle() to file stream classes (basic_filebuf, basic_ifstream, basic_ofstream, basic_fstream) to return a native_handle_type. The aim is to enhance the use of iostreams with OS-specific operations without having to reopen files.

For example:

std::ofstream of("foo.txt");
auto nativeHandle = of.native_handle();  // New method
// Now you can perform platform-specific operations with nativeHandle

The proposal does not support constructing a file stream from a native handle nor getting a native handle from a FILE*.

Over to You  

What are your favorite proposals that could be included in the next C++ Standard?

Share your thoughts in the comments section below the article.