The Summer 2018 ISO C++ standards committee meeting this year was back in Rapperswil, Switzerland. The new features for C++2a are coming fast now; the Core language working group had very little time for issue processing because of all the proposal papers coming to us from the Evolution working group.
Red Hat sent three of us to the meeting, to cover different tracks: myself (Core), Jonathan Wakely (Library), and Torvald Riegel (Parallelism/Concurrency). Overall, I thought the meeting was very successful; we made significant progress in a lot of areas.
New C++ language features that were accepted at this meeting:
Accepted features
Contracts—This feature provides a structured way to express function preconditions and postconditions in code, e.g.
int f(int x) [[expects: x>0]] [[ensures r: r>0]];
Literal class types for non-type template parameters—These will roughly have the semantics of a reference to a constexpr variable.
Destroying operator delete—One use of this feature is for cases when a class is allocated together in a block with other data, such as a trailing buffer. Where in C++17 deleting a pointer to such a class would call sized ::operator delete with the wrong size, with this proposal the user can adjust the size appropriately.
Allowing virtual function calls in constant expression evaluation—This one is somewhat self explanatory.
explicit(bool)—Various wrapper types in the C++ standard library currently need to use SFINAE with two separate constructors in order to make construction explicit based on whether construction of the wrapped type(s) is explicit. With this feature library writers can write a single conditionally-explicit constructor instead.
One semantic change that I wanted to call attention to:
Prohibit aggregates with user-declared constructors—Currently, some code uses patterns like:
struct A { A() = delete; // prohibit default-initialization B b; }; A a = { B(); }; // OK, aggregate initialization
to encourage users of the A type to use aggregate initialization. But this also allows:
A a = { }; // also aggregate initialization
and the deleted default constructor might also have been intended to prevent this, since it's also initializing from no elements. So this proposal changes A, or any class with a user-declared constructor, to be non-aggregate; if the A author wants aggregate initialization, they must remove the default constructor declaration. I argued that there should be an exception for copy and move constructors, but lost. But it is still possible to prevent default initialization of an aggregate by using a trailing empty member with the recently added [[no_unique_address]] attribute:
struct B { B(); }; struct deleted_default { deleted_default() = delete; }; struct A { B b; [[no_unique_address]] deleted_default _d; // prevent default-initialization }; A a; // error, deleted implicitly-declared default constructor A a2 { }; // ok, aggregate initialization A a3 { B() }; // ok, aggregate initialization
Papers that weren't accepted
There were several more papers that we worked on, but weren't ready by the end of the week, including:
- char8_t type for UTF-8 characters, to go along with the existing char16_t and char32_t types. char8_t will not have the problematic aliasing properties of plain char.
- parenthesized initialization of aggregate classes, to be treated in overload resolution like a built-in constructor taking the types of the aggregate elements.
Concepts, Modules, and Coroutines
The big three feature TSes (technical specifications) are still working toward consensus.
- Concepts (partially merged last year)—There was a lot of discussion about terse function declaration syntax, exploring alternatives to the syntax in the TS, and I think things are looking hopeful for a successful compromise at the next meeting.
- Modules—Modules also seem to be on track for successful compromise; there was consensus for merging some of the ATOM proposal into the TS working paper, and we'll see the result at the next meeting.
- Coroutines—Merging the coroutines TS was up for a vote at the end of the meeting, but failed. There was an alternative proposal considered at the meeting, but the next step isn't as clear to me here as it is with Concepts and Modules.
We also voted to send out the (static) Reflection TS for public comment at this meeting. This proposal uses meta-types as the handle through which the user can ask questions about the program, in much the same way that type traits use class templates.
One broadly interesting bit from discussion of core issues at the end of the week:
2335—There seems to be a growing consensus in the core working group (CWG) that we should be more flexible about dependencies between delayed-parse regions, allowing on-demand parsing in much the way we do on-demand instantiation of such regions in a class template. This has previously been deemed impractical, but there is less concern about that now.
The next meeting will be in San Diego in November.
Last updated: March 24, 2023