Trip report: Evolution Working Group at the Summer ISO C++ standards meeting (Toronto)

Andrew

July 28th, 2017

点这里看中文版

The Summer 2017 ISO C++ standards meeting was held in July 10-15 at the University of Toronto. Many thanks to Google, Codeplay, and IBM for sponsoring the event, as well to folks from Mozilla, Collège Lionel-Groulx, Christie Digital Systems, and Apple for helping to organize. And, of course, we very much appreciate Waterfront International for sponsoring a banquet at the CN Tower.

We had a productive and rather harmonious Evolution Working Group (EWG) session this year in Toronto. There were 45 proposals discussed over five days and three evening sessions: a Tuesday night session on Concepts and a Thursday night joint session with SG7, the Reflection and Metaprogramming Study Group. Most of us also participated in the Monday night session on P0684R0, C++ Stability, Velocity, and Deployment Plans.

C++ Standards Committee meetings are a lot of hard work: four-hour sessions spent in smaller working groups like EWG every morning and afternoon, and a few hours spent on a topic in-depth most evenings. And on Saturday there’s a closing Plenary session with the whole group of roughly 120 experts who came from around the world to attend the meeting. But it all goes smoothly because there’s a lot of work done between meetings by the officers of WG21, the subgroup chairs, and of course the paper authors and all the attendees who (should have) read most of the papers they’ll be discussing before the presentations. There’s more work done between meetings to improve proposals: very few significant proposals are accepted on their first presentation. As Herb Sutter, Convener of WG21 says, “smooth never happens by accident.” You’ve got to be prepared if you want things to go smoothly.

There are many trip reports available online written by everyone from experienced participants to first-timers. This report is intentionally narrow. It focuses on the Evolution Working Group, where I spend my time as the working group’s scribe. This report meant to be a summary of EWG’s work in Toronto rather than an explanation of the whole C++ standards working group’s (WG21) progress.

Links are provided for all papers. The linking service should automatically forward to the latest revision of the paper, not necessarily the version discussed in Toronto. If the paper you view has a larger revision number (e.g., PxxxxR1 instead of PxxxxR0) it should incorporate feedback from the Toronto discussions.

Concepts Technical Specification merged into the draft Standard

The biggest news of the Toronto meeting is that we merged the Concepts TS into the C++ draft standard for C++20. The presentations capped off with a marathon evening session regarding removal of the template introducer syntax and the “natural syntax”. The stated goal of this proposal, P0696R0, is to remove contentious parts of the Concepts syntax so that we could successfully merge the TS into the draft Standard.

The main argument raised in favor of the natural syntax (also called “abbreviated” or “terse” syntax) is that it supports generic programming, specifically Stepanov-style Generic Programming. The emphasis is on the usage, not the language itself. Simplifying the usage of the language promotes sound programming styles and paradigms.

After much discussion, the group voted to remove these two syntaxes, noting that we can add the natural syntax in later. Examples raised were the fact that we didn’t include generic lambdas when we introduced lambdas, and constexpr expanded greatly in its capabilities from its introduction in C++11. EWG is committed to bringing back an abbreviated syntax in future meetings, ideally before C++20 is finished.

We had six discussions on the topic of Concepts. The discussions are listed in chronological order. Later discussions can partially override decisions of earlier discussions.

Richard Smith, Project Editor for the working draft, and Andrew Sutton, Project Editor for the Concepts TS, presented two papers, each of which received strong support. P0717R0: This proposal simplified the rules for determining if two constraints are equivalent. Previously, implementations had to compare concepts for equivalency token-by-token. P0716R0: Before the February 2017 meeting we had two ways of writing concepts: one as a function, one as a variable. This proposal unified the concept definition syntax. Specifically, it removed the keyword bool and other complexities of the variable declaration syntax.

P0691R0 lists current issues with the Concepts TS. We addressed only Issue 21: Require parentheses around requires clauses to help with parsing: requires(bool(T))) .

clauses to help with parsing: . P0694R0: This paper accompanies a presentation from Bjarne Stroustrup on a “natural” syntax for function declarations using concepts.

P0696R0: The Tuesday night discussion concerned this proposal–see above for a summary.

The last discussion, on Wednesday afternoon, was to clarify to the Core Working Group (Core) that an auto in a template argument of a type of a variable or a parameter declaration or a return type should not be valid. The discussion was meant to tie up some loose ends from Tuesday night’s decisions.

Modules Technical Specification sent out for PDTS

The big news in EWG would have been the progress we made on the Modules TS if Concepts hadn’t stolen the show. Representatives from Google and Microsoft talked about their experience adopting modules and compiler implementers proposed clarifications and modifications to the TS wording. At the closing Plenary meeting we sent the Modules TS out for its comment and approval ballot, known as PDTS. Going to PDTS early in the C++20 cycle increases the chances of polishing C++ Modules in time for inclusion in C++20.

We had eight discussions on Modules:

P0629R0: The paper proposes a syntax, export module M; to distinguish interfaces from implementations. Currently the only way a compiler knows if it’s compiling an interface or an implementation is a command line option or a file suffix. We approved this proposal and sent Nathan Sidwell (Facebook), implementer for GCC’s modules, off to Core.

to distinguish interfaces from implementations. Currently the only way a compiler knows if it’s compiling an interface or an implementation is a command line option or a file suffix. We approved this proposal and sent Nathan Sidwell (Facebook), implementer for GCC’s modules, off to Core. P0584R0: We did not reach consensus on module interface partitions—being able to split interfaces across multiple files. It’s clear some developers want partitions but it wasn’t clear to EWG members what changes should be made.

Nathan Sidwell (Facebook) also presented about some ambiguous wording in the Modules TS. Gabriel Dos Reis, editor of the Modules TS, captured these on the Modules TS Issues list.

P0721R0: Regarding ambiguity on the export of using declarations. We identified that the wording is ambiguous but did not reach a plan of action in the meeting. We left this for Nathan and Gabriel to finalize.



P0714R0: Regarding exporting entities with identical names in and out of a namespace scope.

Representatives from Bloomberg presented P0678R0, listing a set of three business requirements for modules. We agreed that the Modules TS as written satisfied these requirements.

Modules must be additive, not invasive, such that a library can be exposed either through header files or modules to different consumers.



Modules can support library interfaces at a higher level of abstraction.



Modules don’t allow fragile transitive inclusions.

Chandler Carruth from Google presented build throughput gains from their experience modifying their build system to automatically convert some common header files to be consumed as Clang modules.

Gabriel Dos Reis from Microsoft presented about his company’s experience and expectations about using modules at scale in the huge Windows codebase and build system.

P0713R0: Daveed Vandevoorde, an implementer of the EDG compiler, proposed that we mark the global module declaration at the top of the file. This allows a compiler parsing a module unit source file to know it’s a module when parsing the top of the file without having to be passed context from the build system, compiler switches, or filename extensions. We’ll adopt this change after the Modules PDTS is published.

Coroutines Technical Specification (and two more!)

And if moving Concepts into the Standard and moving Modules to PDTS wasn’t enough, the larger WG21 group also completed our review of the Coroutines TS, the Networking TS, and the Ranges TS. EWG’s part was to clarify that a couple of issues on the Coroutines TS (CH001 and US013) are not defects that should prevent merging the Coroutines TS into the draft Standard. See P0664R0 for more details.

C++20 is shaping up to be an exciting release!

Other evening sessions

In addition to the evening session on Concepts, we also had evening sessions with SG7, the Reflection and Metaprogramming Study Group, and a session on C++ Stability, Velocity, and Deployment Plans (P0684R0).

Many papers were discussed at Thursday’s SG7 meeting, including P0670R0, P0425R0, P0707R0, and P0712R0. P0327R2 was handled by directly by EWG in a daytime session. You can read more about the metaprogramming papers in Herb Sutter’s post: Metaclasses: Thoughts on generative C++.

One topic at Monday’s evening session on the future of C++ was about whether we can actually break code by removing deprecated features from the Standard. P0619R1, heard in EWG a couple of days later highlighted many deprecated features that could potentially be removed. After discussing three of these that concerned the core language (as opposed to library changes) we decided the only one that could be removed was throw() , which has been deprecated for three standards.

Proposals sent to Core

Four proposals were sent to Core during this meeting. When a proposal is forwarded to Core it means that EWG has approved the design and requests that Core review wording to include this proposal in the draft Standard. It might appear that a proposal is done at this point, but it’s really only about halfway done. From the EWG perspective this is the end of the journey but it’s a long way to being part of a published Standard.

The following proposals were forwarded to Core:

P0683R0: We previously decided we want a syntax for bitfield default member initialization. This proposal narrowed down the syntax choice.

P0641R0: This paper concerned Issue 1331 raised by Core. The issue surfaced with wrapper types where a constructor with a parameter that is a reference to non- const can conflict with the defaulted copy.

can conflict with the defaulted copy. P0634R0 proposed that the typename keyword be optional, e.g., template<class T> struct D: T::B { // No `typename` required here

keyword be optional, e.g., P0614R0: This proposed a new range-based for (init; decl : expr) that allows initialization statements in the for statement itself rather than require that the initialization statement precede the for statement.

A few other proposals were approved by EWG but not sent immediately to Core. Some were sent to the Library Evolution Working Group (LEWG) for more work from a different perspective. Others were approved to go to Core, but not until the November meeting in Albuquerque. See below for a little more information on these, as well as some that were rejected by EWG.

Other proposals in design

WG21 is primarily a design group, and EWG’s main activity is discussing how the language should evolve. We entertained, advanced, considered, and rejected many other proposals. Here’s a list of everything else we discussed, sorted loosely into a few general topics.

Feature test macros

We had three presentations on the future of feature test macros: P0697R0, P0723R0, and a presentation called “Feature Test Macros Considered Harmful”. After much debate we decided on a small change from status quo: the document concerning feature test macros, SD-6, will remain a WG21-authored specification but we will plan to have it formally approved by WG21 as a Standing Document in a group-wide Plenary session.

Structured bindings

P0609R0: This proposal allowed for attributes such as [[maybe_unused]] on the members of structured bindings.

Memory

P0132R0 Explores non-throwing containers for memory-constrained environments.

P0639R0: In past meetings we’ve talked about constexpr_vector and constexpr strings. The options considered were allocators that work in a constexpr context or have new and delete work in constexpr contexts. This proposal received strong support and will return in a future meeting.

and strings. The options considered were allocators that work in a context or have and work in contexts. This proposal received strong support and will return in a future meeting. P0722R0 proposes another form of operator delete() for variable sized classes. The discussion opened up a lot of questions that need to be answered before the proposal moves forward.

Argument deduction, lookup, type detection, specialization

P0702R0: This paper addresses design clarifications for class template argument deduction. It advances ideas proposed before to EWG.

P0389R0: This paper proposed wording clarifications to help with argument-dependent lookup for some calls to function templates. We realized during discussion that we could in fact remove the template keyword in these calls altogether. A new paper is forthcoming.

keyword in these calls altogether. A new paper is forthcoming. P0672R0: Provides a method to syntax to allow type detection for proxies and expression templates. It also proposes a noeval() to disable implicit evaluation but still allow automatic type deduction.

to disable implicit evaluation but still allow automatic type deduction. P0665R0 Allows specializing class templates in a different namespace using fully qualified names. This helps to preserve code locality.

Lambdas

P0624R0: This proposes default constructible and assignable stateless lambdas, allowing them to be used where function objects are today. Programmers—or meta-programmers—could create in-line a piece of code that can be stored and retrieved from the type system.

P0238R1: This proposal aims to make lambdas more useful with constrained libraries. It received strong support as well as encouragement to work on a terser lambda syntax.

Indexing into bitfields and tuple-like types

P0573R1: We encouraged the bit_sizeof and bit_offset operators to wait for the Reflection study group to make progress that can enable these operators.

and operators to wait for the Reflection study group to make progress that can enable these operators. P0327R2 concerns std::product_type . We don’t yet have a syntax to propose product type operators to get the size and nth element. Expect this to return to EWG.

Precise assertions & marking unreachable code

P0681R0: Lisa Lippincott continued examining the precise semantics of assertions. At the end of this presentation we identified three proposals we’d like to see explored further, two in EWG in conjunction with Contracts, and one, std::unreachable , in LEWG.

, in LEWG. P0627R2: A std::unreachable type was endorsed and forwarded to LEWG for further discussion.

type was endorsed and forwarded to LEWG for further discussion. P0627R1: This proposal suggests an attribute to mark unreachable code similar to __builtin_unreachable() or __assume(false) .

Proposals that we discouraged

Some proposals, no matter how well-reasoned and insightful they may be, are just not seen to be a good fit for the language at this time. Some proposals seem like they would introduce too much complexity if adopted. Others are just good ideas that won’t fit in the language. EWG discouraged further work on the following proposals unless there are fundamental changes to the approach that would make them more palatable to the group.

P0312R1: This paper proposed making pointers to members callable for the benefit of generic code. It had neither strong support nor opposition amongst the group, but faces strong National Body opposition. Because a draft Standard cannot be approved without National Body consensus it’s incumbent upon the author to work to achieve this consensus before we can move forward.

P0671R0: Named function parameters—or “parametric functions” are a common feature in other languages. They have been repeatedly suggested for C++ in different forms, but the syntactic implications are difficult to work through.

P0654R0: Add explicit to a struct to require all members be initialized. This proposal is interesting, but as compilers can verify that all members are initialized possibly we’d want the opposite approach to suppress the compiler’s verification on a struct .

to a to require all members be initialized. This proposal is interesting, but as compilers can verify that all members are initialized possibly we’d want the opposite approach to suppress the compiler’s verification on a . P0637R0: allow the lambda by-value capture of *this to rebind this to arbitrary objects. In a lambda, capture of *this can only be captured by name, not by initializer. This proposal is for an init-capture *this .

In closing

It was a great meeting and, as always, a ton of work. It’s amazing to think that a group of 120-ish people can meet and decide on anything, but we accomplished quite a bit at the Toronto meeting. I’m personally looking forward to our meeting in Albuquerque this November where we can keep building an amazing C++20 release!

And as always, thank you to the hundreds of people who provide feedback and help us improve the C++ experience in Visual Studio. If you have any feedback or suggestions for our team, please let us know. We can be reached via the comments below, via email (visualcpp@microsoft.com) and you can provide feedback via Help > Report A Problem in the product, or via Developer Community. You can also find us on Twitter (@VisualC) and Facebook (msftvisualcpp).