C++23 is Coming!

Get Ready for C++23

By Jeff Tranter

C++23 is the next ISO/IEC 14882 standard for the C++ programming language. Slated for release in December 2023, it will replace the previous C++20 standard (C++ standards are on a fixed three-year release cycle).

While the contents of the standard are still subject to change, they are pretty much finalized at this point.

Compared to some previous C++ standard releases, C++23 for the most part introduces small changes that will not greatly impact how people write code. Most fall into one of these categories: incremental improvements to C++, clarifications to the previous behavior, and removal of previously deprecated features or relaxing of restrictions.

Feature Test Macros

It is worth mentioning that most C++ features can be tested for at compile time using feature test macros. This allows you to determine if a feature is present and have your code handle it accordingly.

For example, the C++23 feature literal suffixes for std::size_t and its signed version can be checked for by the preprocessor symbol __cpp_size_t_suffix being defined and having the value 202011L if the compiler supports it.

You can look up the specific macros in the standard (and some of the references listed later).

Compiler Support

Depending on the compiler you use, many C++23 features are already supported.

Most C++23 features are supported by GCC 12 (and many in GCC 11) and by Clang 13 and later. At the time of writing, the most recent release of Microsoft Visual C++ did not yet support most C++23 features.

On Linux, depending on the Linux distribution and version you are using, you may have an older compiler than the most recent (for example, the Latest Ubuntu 22.04.01 LTS release has gcc 11).

Some Specific Features of Interest

I don't have room here to cover all C++23 features, and some are still evolving, but I will mention a few of note.

Removing Garbage Collection Support

C++ defines some support for implementations of garbage collection, and there are several implementations of garbage collected C++. However, it turned out that in practice the implementations were very different and standardization was not helpful as no implementations fully followed the standard. C++23 proposes to remove (not just deprecate) C++'s garbage collection support. Specifically, it removes five library functions, an enum, a macro, and relevant references to garbage collection in the standard.

C++ Identifier Syntax using Unicode Standard Annex 31

C++23 proposes to follow Unicode standard UAX #31, Unicode Identifier and Pattern Syntax, to define what Unicode characters are valid in identifiers in source code. This clarifies what characters should be supported and disallows some (like emojis) that don't really make sense in identifiers.

Allow Duplicate Attributes

Since C++11 you can add implementation-defined attributes for types, objects, code, etc. Examples include [[noreturn]], [[deprecated]], and [[fallthrough]]. Previously there was a requirement that every standard attribute could appear at most once in an attribute list. In C++23 that restriction is removed as it was not particularly useful.

Trimming Whitespace Before Line Splicing

There was some ambiguity about the behavior with whitespace after a backslash in source code. It was handled differently by different compilers, although most compilers generate a warning. C++23 proposes to trim all trailing whitespace before handling backslash splicing so that the behavior is defined.

Make Declaration Order Layout Mandated

The C++ standard allowed compilers to reorder class members in the layout if they have different access control (i.e. public/protected/private). In practice, no commonly used compilers did this. In C++23 the standard is being revised to make the layout always be created using the declaration order.

Removing Mixed Wide String Literal Concatenation

String concatenation involving string literals with encoding prefixes mixing L"", u8"", u"", and U"" was conditionally supported with implementation-defined behavior. Although allowed in C++11, all known C++ compilers reject such concatenation, and the actual use of this feature is thought to be extremely rare. As a result, allowing mixed wide string literal concatenation is being removed in C++23.

Explicit Object Parameter (Deducing this)

In C++23 a non-static member function can be declared to take as its first parameter an explicit object parameter, denoted with the prefixed keyword this. For example:

struct X
{
void foo(this X const& self, int i); // same as void foo(int i) const &;
void bar(this X self, int i);        // pass object by value: makes a copy of *this
};

For template member functions, an explicit object parameter allows deduction of the type and value category. This language feature is called deducing this.

#elifdef and #elifndef

C++23 adds two more conditionals to the pre-processor: #elifdef identifier (which is essentially equivalent to #elif defined identifier) and #elifndef identifier (essentially equivalent to #elif !defined identifier).

Multidimensional Subscript Operator

In C++23, user-defined types can define a subscript operator that can take more than one subscript. For example, an operator[] of a 3D array class declared as T& operator[](std::size_t x, std::size_t y, std::size_t z); can directly access the elements.

Note that the syntax of accessing the elements is a[i,j,k] and not a[i][j][k] or a(i,j,k) as in some other programming languages.

In theory, this could break existing code that uses the comma operator, but this was deprecated in C++20 to alert programmers and minimize the likelihood of this happening.

Preprocessor #warning Directive

Another small improvement to the preprocessor is a new #warning directive which displays a warning message and continues compilation. This is similar to #error, but does not stop compilation.

Summary

C++23 should be official by the end of this year and introduces some incremental improvements and clarifications of behavior. Typically it takes time (sometimes years) before new features can be widely used in production code, particularly if you are locked into an older compiler. But given that, it's worth reviewing the new features so you can make use of them in new code, and by use of the feature test macros you can get your code ready for these new features even if they are not available to you yet.

References

Here are a few references that I can found useful and relevant to C++23:

  1. https://en.wikipedia.org/wiki/C%2B%2B23
  2. https://en.cppreference.com/w/cpp/23
  3. https://isocpp.org/std/status
  4. https://handwiki.org/wiki/C%2B%2B23