November 2015

2015-11 post-Kona mailing available

The 2015-11 mailing of new standards papers is now available.

NOTE: A number of these papers have already been publicized on this blog. This is the complete list including ones not previously publicized.

 

WG21 Number Title Author Document Date Mailing Date Previous Version Subgroup Disposition
SD-1 2015 PL22.16/WG21 document list John Spicer 2015-11-16 2015-11      
2015-11 post-Kona
N4553 Working Draft, C++ extensions for Concepts Andrew Sutton 2015-10-02 2015-11 N4549 Concepts  
N4554 Editor's report for the Concepts TS Andrew Sutton 2015-10-02 2015-11   Concepts  
N4555 February 2016 WG21 Meeting Barry Hedquist 2015-10-09 2015-11      
N4556 WG21 telecon minutes Marhsall Clow 2015-10-09 2015-11      
N4557 WG21 2015-07-20 Telecon (revised) Roger Orr 2015-10-24 2015-11      
N4558 Kona WG21 Minutes Jonathan Wakely 2015-11-16 2015-11      
N4559 Kona PL22.16 Minutes Jonathan Wakely 2015-11-16 2015-11      
N4560 Working Draft, C++ Extensions for Ranges Eric Niebler, Casey Carter 2015-11-06 2015-11      
N4561 Ranges Editor's Report Eric Niebler 2015-11-05 2015-11      
N4562 Working Draft, C++ Extensions for Library Fundamentals, Version 2 Geoffrey Romer 2015-11-05 2015-11 N4529    
N4563 Editor's Report for the Library Fundamentals TS Geoffrey Romer 2015-11-05 2015-11      
N4564 C++ Extensions for Library Fundamentals, Version 2 PDTS Geoffrey Romer 2015-11-05 2015-11      
N4565 Record of Response: National Body Comments ISO/IEC PDTS 19571 Technical Specification: C++ Extensions for Concurrency Barry Hedquist 2015-11-06 2015-11      
N4566 Editor's Report -- Working Draft, Standard for Programming Language C++ Richard Smith 2015-11-09 2015-11      
N4567 Working Draft, Standard for Programming Language C++ Note: Richard Smith 2015-11-09 2015-11 N4527    
P0001R1 Removing Deprecated Register Keyword Alisdair Meredith 2015-10-21 2015-11 P0001R0 Core Adopted 2015-10
P0002R1 Removing Deprecated Operator++ for bool Alisdair Meredith 2015-10-23 2015-11 P0002R0 Core Adopted 2015-10
P0004R1 Removing Deprecated Aliases in iostreams Alisdair Meredith 2015-10-19 2015-11 P0004R0 Library Evolution  
P0005R1 Adopt not_fn from Library Fundamentals 2 for C++17 Alisdair Meredith, Stephan T. Lavavej, Tomasz Kamiński 2015-10-18 2015-11 P0005R0 Library Revised P0005R2
P0005R2 Adopt not_fn from Library Fundamentals 2 for C++17 Alisdair Meredith, Stephan T. Lavavej, Tomasz Kamiński 2015-10-23 2015-11 P0005R1 Library  
P0007R1 Constant View: A proposal for a std::as_const helper function template ADAM David Alan Martin, Alisdair Meredith 2015-10-22 2015-11 P0007R0 Library Evolution  
P0012R1 Make exception specifications be part of the type system, version 5 Jens Maurer 2015-10-22 2015-11 P0012R0   Adopted 2015-10
P0013R1 Logical Operator Type Traits (revison 1) Jonathan Wakely 2015-10-23 2015-11 P0013R0 Library Evolution Adopted 2015-10
P0014R1 Proposal to add the multiline option to std::regex for its ECMAScript engine Nozomu Katō 2015-10-30 2015-11 P0014R0 Library Evolution  
P0017R1 Extension to aggregate initialization Oleg Smolsky 2015-10-24 2015-11 P0017R0 Evolution  
P0018R1 Lambda Capture of *this by Value H. Carter Edwards, Christian Trott, Hal Finkel, Jim Reus, Robin Maffeo, Ben Sander 2015-10-23 2015-11 P0018R0 Evolution  
P0022R1 Proxy Iterators for the Ranges Extensions Eric Niebler 2015-11-06 2015-11 P0022R0 Library  
P0025R1 An algorithm to "clamp" a value between a pair of boundary values Martin Moene, Niels Dekker 2015-10-29 2015-11 P0025R0 Library  
P0030R1 Proposal to Introduce a 3-Argument Overload to std::hypot Benson Ma 2015-11-06 2015-11 P0030R0 Library  
P0032R1 Homogeneous interface for variant, any and optional (Revision 1) Vicente J. Botet Escriba 2015-11-05 2015-11 P0032R0 Library Evolution  
P0051R1 C++ generic overload function (Revision 1) Vicente J. Botet Escriba 2015-11-05 2015-11 P0051R0 Library Evolution  
P0057R1 Wording for Coroutines Gor Nishanov 2015-11-06 2015-11 P0057R0 Core, Library Evolution  
P0061R1 __has_include for C++17 Clark Nelson 2015-10-23 2015-11 P0061R0   Adopted 2015-10
P0083R1 Splicing Maps and Sets (Revision 3) Alan Talbot, Jonathan Wakely, Howard Hinnant, James Dennett 2015-11-07 2015-11 P0083R0 Library Evolution  
P0092R1 Polishing Howard Hinnant 2015-10-20 2015-11 P0092R0 Library Evolution  
P0100R1 Comparison in C++ Lawrence Crowl 2015-11-07 2015-11 P0100R0 Library Evolution  
P0112R1 Networking Library (Revision 7) Christopher Kohlhoff 2015-10-23 2015-11 P0112R0 Library Evolution Adopted 2015-10
P0136R1 Rewording inheriting constructors (core issue 1941 et al) Richard Smith 2015-10-19 2015-11 P0136R0 Core Adopted 2015-10
P0144R0 Structured Bindings Herb Sutter 2015-10-14 2015-11   Evolution  
P0145R0 Expression Order of Evaluation Gabriel Dos Reis, Herb Sutter, Jonathan Caves 2015-10-01 2015-11   Evolution  
P0147R0 The Use and Implementation of Contracts Lawrence Crowl 2015-11-08 2015-11   Evolution  
P0148R0 memory_resource_ptr: A Limited Smart Pointer for memory_resource Correctness Pablo Halpern, Dietmar Kühl 2015-10-14 2015-11   Library Evolution  
P0151R0 Proposal of Multi-Declarators Andrew Tomazos 2015-10-16 2015-11   Evolution  
P0152R0 constexpr atomic::is_always_lock_free Olivier Giroux, JF Bastien, Jeff Snyder 2015-10-21 2015-11 N4509 Concurrency  
P0153R0 std::atomic_object_fence(mo, T&&...) Olivier Giroux, JF Bastien 2015-11-05 2015-11 N4522    
P0154R0 constexpr std::thread::hardware_{true,false}_sharing_size JF Bastien, Olivier Giroux 2015-10-24 2015-11 N4523    
P0155R0 Task Block R5 Pablo Halpern, Arch Robison, Hong Hong, Artur Laksberg, Gor Nishanov, Herb Sutter 2015-10-22 2015-11 N4411 Library Adopted 2015-10
P0156R0 Variadic lock_guard (Rev. 3) Mike Spertus 2015-10-21 2015-11 N4498 Evolution  
P0157R0 Handling Disappointment in C++ Lawrence Crowl 2015-11-07 2015-11   Evolution  
P0158R0 Couroutines belong in a TS Jamie Allsop, Jonathan Wakely, Christopher Kohlhoff, Anthony Williams, Roger Orr, Andy Sawyer, Jonathan Coe, Arash Partow 2015-11-06 2015-11   Evolution  
P0159R0 Draft of Technical Specification for C++ Extensions for Concurrency Artur Laksberg 2015-10-22 2015-11     Adopted 2015-10
P0160R0 Wording for removing defaults for unary folds Jens Maurer 2015-10-23 2015-11   Core  
P0162R0 A response to "P0055R0: On Interactions Between Coroutines and Networking Library" Christopher Kohlhoff 2015-11-06 2015-11      
P0163R0 shared_ptr::weak_type Arthur O'Dwyer 2015-10-23 2015-11   Library Evolution  
P0164R0 Core Language Working Group "ready" Issues William M. Miller 2015-10-23 2015-11   Core Adopted 2015-10
P0165R0 C++ Standard Library Issues to be moved in Kona Marshall Clow 2015-10-23 2015-11   Library Adopted 2015-10
P0166R0 Three interesting questions about contracts J. Daniel Garcia 2015-11-06 2015-11   Evolution  
P0167R0 Core Language Working Group "ready" Issues after the October, 2015 (Kona) meeting William M. Miller 2015-11-10 2015-11   Core  
P0169R0 regex and Unicode character types Nozomu Katō 2015-11-03 2015-11   Library evolution  
P0170R0 Wording for Constexpr Lambda Faisal Vali 2015-11-01 2015-11 N4487 Evolution  
P0171R0 Response To: Resumable Expressions P0114R0 Gor Nishanov 2015-11-06 2015-11   Evolution  
P0172R0 Abominable Function Types Alisdair Meredith 2015-11-10 2015-11   Library Evolution  

 

C++ meetup in Madrid, Spain: C++ in the video game industry.

Yes! A new edition of the local C++ meetup will take place on the 4th of December at Google Campus' facilities. All the info and RSVPs below:

C++ en la industria del videojuego

by Jordi Mon Companys.

What to expect?

Jose Daniel García will moderate a table of experts in gamedev in C++ that will friendly elbaorate on the state of the language on regards to gamedev, its advantages and threats. Afterwards we will join forces with Product Hunt Madrid and we will have the chance to hear how King develops its games and how a group of students from U-Tad university have managed to get their game nominated to the Play Station Awards. We will water down our thoughts and reflections with plenty of beer thanks to King.com's sponsorship.

Breaking all the Eggs in C++ -- Scott Meyers

Scott Meyers takes a deeper look into uninitialized memory in his recent blog post.

Breaking all the Eggs in C++

by Scott Meyers

From the article:

If you want to make an omelet, so the saying goes, you have to break a few eggs. Think of the omelet you could make if you broke not just a few eggs, but all of them! Then think of what it'd be like to not just break them, but to replace them with newer, better eggs. That's what this post is about: breaking all the eggs in C++, yet ending up with better eggs than you started with.

NULL, 0, and nullptr

NULL came from C. It interfered with type-safety (it depends on an implicit conversion from void* to typed pointers), so C++ introduced 0 as a better way to express null pointers. That led to problems of its own, because 0 isn't a pointer, it's an int. C++11 introduced nullptr, which embodies the idea of a null pointer better than NULL or 0. Yet NULL and 0-as-a-null-pointer remain valid. Why? If nullptr is better than both of them, why keep the inferior ways around?

Backward-compatibility, that's why. Eliminating NULL and 0-as-a-null-pointer would break exiting programs. In fact, it would probably break every egg in C++'s basket. Nevertheless, I'm suggesting we get rid of NULL and 0-as-a-null-pointer, thus eliminating the confusion and redundancy inherent in having three ways to say the same thing (two of which we discourage people from using).

CppCast Episode 34: High Performance Computing with Dmitri Nesteruk

Episode 34 of CppCast the only podcast for C++ developers by C++ developers. In this episode Rob and Jason are joined by Dmitri Nesteruk to talk about High Performance Computing and some of the new features coming to Clion and ReSharper for C++ from JetBrains.

CppCast Episode 34: High Performance Computing with Dmitri Nesteruk

by Rob Irving and Jason Turner

About the interviewee:

Dmitri Nesteruk is a developer, speaker, podcaster and a technical evangelist at JetBrains. His interests lie in software development and integration practices in the areas of computation, quantitative finance and algorithmic trading. His technological interests include C#, F# and C++ programming as well high-performance computing using technologies such as CUDA. He has been a C# MVP since 2009.

HPX version 0.9.11 released -- STE||AR Group

The STE||AR Group has released V0.9.11 of HPX -- A general purpose parallel C++ runtime system for applications of any scale.

HPX V0.9.11 Released

The newest version of HPX (V0.9.11) is now available for download! Please see here for the release notes.

HPX exposes an API fully conforming to the concurrency related parts of the C++11 and C++14 standards, extended and applied to distributed computing.

From the announcement:

  • In this release our team has focused on developing higher level C++ programming interfaces which simplify the use of HPX in applications and ensure their portability in terms of code and performance. We paid particular attention to align all of these changes with the existing C++ Standard or with the ongoing standardization work. Other major features include the introduction of executors and various policies which enable customizing the ‘where’ and ‘when’ of task and data placement.
  • This release consolidates many of the APIs exposed by HPX. We introduced a new uniform way of creating (local and remote) objects, we added distribution policies allowing to manage and customize data placement and migration, we unified the way various types of parallelism are made available to the user.

Introduction to Variable Templates of C++14--Yu Xuan Zhang

Do you know about variable templates?

Introduction to Variable Templates of C++14

by Yu Xuan Zhang

From the article:

The variable template, which comes from N3651, is one of the major proposals in Standard C++14. The main purpose of the variable template is to simplify definitions and uses of parameterized constants.

Rules before C++14 do not allow declaring a variable using a template declaration. There are workarounds for this problem before C++14, but they are either redundant or complicated...

Trip Report: C++ Standards Meeting in Kona, October 2015--Botond Ballo

Another trip report of the last meeting in Kona:

Trip Report: C++ Standards Meeting in Kona, October 2015

by Botond Ballo

From the article:

Last week I attended a meeting of the ISO C++ Standards Committee in Kona, Hawaii. This was the second committee meeting in 2015; you can find my reports on the past few meetings here (June 2014, Rapperswil), here (November 2014, Urbana-Champaign), and here (May 2015, Lenexa). These reports, particularly the Lenexa one, provide useful context for this post.

The focus of this meeting was primarily C++17. There are many ambitious features underway for standardization, and the time has come to start deciding what which of them will make C++17 and which of them won’t. The ones that won’t will target a future standard, or a Technical Specification (which can eventually also be merged into a future standard). In addition, there are a number of existing Technical Specifications in various stages of completion...

Kona standards meeting trip report

Kona Standards Meeting Trip Report

Bjarne Stroustrup

Morgan Stanley

Introduction

I’m writing this immediately after the October 19-26, 2015 ISO C++ standards meeting in Kona, Hawaii. I expect that this report will make you drool for some of the new features, make you terribly frustrated from not being able to use them right away, and a bit worried that some instability might ensure. If you also feel inspired to help or to experiment, so much the better.

I am describing features aimed for C++17, but this not is not science fiction. Essentially all features exist in experimental form and some features are already shipping so that you will soon be able to experiment with them. If all you are interested in is what you can use in production tomorrow, please stop reading here. If you want a view of where C++ is going over the next couple of years, please read on and try to imagine what we could do better with the new facilities.

When people hear “Kona” and “Hawaii”, they immediately think something like “loafing on the beach.” Well, the meetings started at 8am and carried on to 10pm with about an hour for lunch an about two for dinner. Outside the formal meetings, there are preparation, document revision, negotiation, setting up collaborations, and more. The large meeting rooms have no A/C, poor ventilation, and are generally very hot and humid. This goes on for six days – well, some of us did stop at 1pm Saturday while others continued until 4pm.

I came into the meeting with a reasonably clear idea of what I wanted (Thoughts about C++17, N4492) and what I could do to get it. At this meeting, I spent all my time in the Evolution Working Group trying to make sure that proposals I considered important progressed and that proposals I deemed wrongheaded, distracting, irrelevant, or not ready did not. Outside that, I spoke with people working on libraries, keeping an eye on the progress there. There is also constant communication between the various working group chairmen, the convener (Herb Sutter from Microsoft), and me: face-to-face, email, and phone.

Apologies for drastically simplifying issues in my summaries. Typically an hour’s serious discussion based on written proposals is reported in less than a paragraph, if at all. If you want more information, follow the links.

As for stability: Long-term stability is a feature. If you want your programs broken every five years, try a proprietary language. The ISO C++ standards committee goes out of its way to avoid breaking old code. That’s one reason ISO standardization is hard.

Organization

Let me give you an idea of scale: I counted 97 people in the room on the first morning. We processed over 140 papers. There are 4 major working groups

  • CWG: Core (chair: Mike Miller, EDG)
  • EWG: Evolution (chair: Ville Voutilainen, Symbio)
  • LWG: Library (chair: Marshall Clow, Qualcomm)
  • LEWG: Library Evolution (chair: Jeffrey Yasskin, Google)

The evolution groups are focused on new “stuff” and the other two on polishing the specification. I chaired the EWG for 25 years before handing it over to Ville to get more time for technical work. In addition, there are several “study groups” looking at specific areas:

Most of these groups met in Kona so that we almost always run 4-way parallel and typically more. This not “four men and a dog” sitting around idly chatting. Rather, it’s a lot of people working devotedly to improve C++. We are all volunteers. There are no full-time C++ standards people. Most are supported by their companies, but there are also individual contributors, some even paying their own way.

You can see this organization described on the Standard C++ Foundation’s Website: www.isocpp.org. Morgan Stanley is a gold member of the Standard C++ Foundation. In general, isocpp.org is an excellent source of information about C++, such as technical videos, articles, blogs, user group meetings, and conferences.

The documents used by the committee are found on the group’s web site:

Below, I refer to paper numbers, such as N4531 and P0013R1. You can find such documents here:

Evening Sessions

There were evening sessions (8pm-10pm or later):

The variant standard-library type. There had been endless discussions (in the committee and elsewhere) about the design of a variant type (a type-safe alternative to unions). We reached consensus on a variant (sic!) of Axel Neumann’s (CERN) proposal (P0086R0, P0087R0, P0088R0). The main difference from previous versions is that it has no undefined behavior (UB is standards jargon).

variant<int,string> v = {“asdf”};

string s = get<string>(v);

v = 42;

string s2 = get<string>(v);            // doesn’t hold a string: throw bad_variant_access 

The same behavior (a throw) happens if we try to retrieve a value from a variant that has been damaged by a failed move- or copy-constructor. This variant can be efficiently and compactly implemented.

Contracts (N4415, N4378): We had two evening sessions. I chaired the first and Herb Sutter the second. The first was (deliberately) quite wide-ranging and the second trying to focus on one simple example. The first reached a result that many found unsatisfactory. The second made further progress. All in all, we appeared to reach a consensus on a design that I happen to like. However, we’ll see how that works out.

Unfortunately, I have been “volunteered” to write it all up with the support of Alisdair Meridith (Bloomberg), Nathan Myers (Bloomberg), Gabriel Dos Reis (Microsoft), and J-Daniel Garcia (U. Carlos III, Madrid). This could be tricky but I expect we’ll be able to write things like this:

T& operator[](int i) [[pre(bad_range{}): 0<=i && i<size()]]
{
    return elem[i];
}

Depending on an assertion level (a build mode), the precondition will be evaluated and if it fails, the specified bad_range{} exception will be thrown. If no exception is mentioned, a global assertion violation handler will be invoked. In addition to preconditions, we should be able to handle postconditions and in-function-body assertions. Many details are still being resolved.

Modules (N4465): I would have preferred for the implementers (primarily Gabriel Dos Reis (Microsoft), Richard Smith (Google), and Jason Merrill (Red Hat)) to be locked up in a room without distractions, but many people turned up so that the discussion became more general, more philosophical, more confused, and less constructive. Sometimes, it is best to let a few experts work out the hard decisions in private. Here is an example:

import std.vector;        // like #include <vector>
import std.string;        // like #include <string>
import std.iostream;      // like #include <iostream>
import std.iterator;      // like #include <iterator >

int main() {
    using namespace std;

    vector<string> v = {
        "Socrates", "Plato", "Descartes", "Kant", "Bacon"
    };

    copy(begin(v), end(v), ostream_iterator<string>(cout, "\n"));
}

I have high hopes for significantly improved compile times from modules. Two approximations of the design exist (Clang and Microsoft, the Microsoft implementation should become available within weeks). Finally, we will be able to state directly how our programs are structured, rather than approximating that through automated copy-and-paste. We get the semantics that Dennis Ritchie wanted for C and I wanted for C++, but was infeasible then. 

The variant and contracts evening sessions had 50+ attendees, the module session a few less than that.

Libraries

Most of the changes are – from a high-level view – minor, but all are important to some groups of programmers. I’ll not list them here. For details, see the trip report from Stephan Lavavej (Microsoft’s standard library expert, usually known by his initials: STL) listed below.

From my perspective the major action was in the new Technical Specifications (TSs):

  • Library Fundamentals TS v2 Papers: Add N4531 and P0013R1 to Working Draft N4529, and send it out for balloting. Several minor improvements.
  • Concurrency TS: N4400  (possibly with minor edits) will be published as the Concurrency TS. It's done! Improved futures and async(). In particular, we can say f.then(cont) so that we can designate that cont is called when f gets ready (rather than having to wait using f.get()).
  • Parallelism TS v2: started with Working Draft N4505 plus P0155R0 "Task Block R5". Together with the first Parallelism TS, this gives us parallel STL algorithms and parallel numeric algorithms under control of a set of execution policies.
  • Networking TS: started with Working Draft P0112R0. This gives us an improved version of Boost’s asio. To quote from the document: “The Boost.Asio library, from which this proposal is derived, has been deployed in numerous systems, from large (including internet-facing HTTP servers, instant messaging gateways and financial markets applications) to small (mobile phones and embedded systems). The asio library supports, or has been ported to, many operating systems including Linux, Mac OS X, Windows (native), Windows Runtime, Solaris, FreeBSD, NetBSD, OpenBSD, HP-UX, Tru64, AIX, iOS, Android, WinCE, Symbian, vxWorks and QNX Neutrino.”
  • Ranges TS: started with Working Draft P0021R0. A revision of the STL parts of the standard library based on Concepts. Provides a general notion of ranges (e.g., pair of iterators, iterator plus element count, and iterator plus sentinel), infinite sequences, composable ranges, and more. In particular, we will be able to say sort(v) rather than sort(v.begin(), v.end()).

Somewhere along the line, we approved array_view [from GSL, and renamed span], string_view [GSL's renamed to string_span, in addition to the existing string_view], optional, and variant.

In aggregate, this is of massive importance. It is a huge amount of foundational library support and most are (or will soon be) available for trying out. One advantage of libraries over language features is that you usually don’t need the next generation compilers to use a library.

See also the Kona trip reports listed at the end of this report.

EWG

I spent most time in the Evolution Working Group (EWG). In fact, I was in that group for every proposal discussed. That turned out to be important. It is also a bit unusual. At most meetings, I get dragged into other groups to help with issues affecting the whole language, its general use, or simply unusually tricky. At this meeting my coordination and fighting bushfires were done over meals and after the evening session.

As usual, Ville Voutilainen ran the EWG meeting with a firm hand so that we managed to get through about 50 proposals. Fortunately, the majority didn’t pass. Some proposal ought to fail. The reasons for that include

  • Poor description of the problem solved
  • Technically poor solution
  • Lack of experience with the solution
  • Concerns about performance implications
  • Concerns about implementability
  • Concerns about compile-time impact
  • Too hard to learn and/or use
  • Doesn’t fit into the language
  • Clumsy syntax or semantics
  • Goes in a direction that the committee doesn’t want to encourage
  • Interferes with another proposal or language feature

If everything else is right, I ask myself: Does it solve a problem on my top-20 list? We can’t accept a feature just because it is good, reasonably designed, and implementable; it must also add significant value to developers. Every feature has a cost: committee time, implementation effort, teaching/learning time for millions of users (now and in the future), and maintenance “forever.”

Weeding out problematic proposals is important. Many are the result of serious work and contain good ideas, so giving feedback to proposers and considering what might become viable in the future is a significant part of the process. Some proposers find that hard to take, but I point out that there is hardly a meeting where I haven’t had one of my proposals rejected. More often than not, I learn from the experience and succeed later, sometimes much later. During a lengthy boring discussion, I amused myself by digging out one of my proposals from 2003 (N1705). I had proposed things like

int f(auto);    // a template taking an argument of any type and returning an int

auto g(int);    // a function returning a value of a type deduced from its return statement

auto h(auto);   // yes, you guessed it smile

We now have that, with the syntax and semantics I proposed. I don’t recall any proposal being less well received. That proposal was incomplete, its motivation insufficiently articulated, flawed in details, and a decade too early for much of the C++ community. Now, we can do better still with concepts. This is a story to remember next time your friends “don’t get” your latest and greatest idea or your proposal is voted down. It happens to us all.

The attendance of EWG varied from just under 20 to over 50. The more important a proposal is perceived to be and how controversial it is determines the attendance. In no particular order:

  • Concepts are now an ISO Technical Specification (N4549), and I guess that we’ll propose it as a part of C++17 itself. Concepts will ship in GCC6.0. The EWG spent quite a while going through comments from various national standard bodies (N4550). We will now be able to use concepts as predicates essentially everywhere (e.g., in static_asserts). All major design issues mentioned were confirmed (that is, no change from the TS).
  • Modules (N4047, N4466). We discussed modules at length. There is a disagreement about whether it should be possible to export macros from a module: Clang does it and Microsoft doesn’t. We all agree that it would be better if we could avoid macro export; the discussion is whether we can. Early reports from Microsoft indicate that we can do it. Modules will be much more useful, safer, and faster if we don’t export macros. Richard Smith (Google) is going to write a paper on this subject.
  • Opaque types (P0109R0). Rejected for being far too complex for the problem solved. This kind of proposal has been considered since 1978 (before my time!) and all solutions have been deemed too complex or too incompatible.
  • Construction rules for enum class values (P0138R0) – providing part of what people want for opaque types:

enum class Index : uint32_t { };    // Note: no enumerator

Index i {42};        // note: no cast

Basically, if you don’t give enumerators, you can use values of the underlying type in {}s. Importantly, this is ABI compatible with the underlying type. This was accepted but versions of it kept bouncing back and forth between EWG and CWG (the Core Working Group, the group that refine Working Paper wording), so details are still up in the air.

  • Default comparisons (N4475, N4476). I proposed that ==, !=, <, <=, >, and >= should be considered part of the language and be automatically generated just like =. That was accepted at the previous meeting. The topics this time were

o   Should <= be generated from < and ==, or just from <? We reaffirmed that we use < and ==. It’s better for floating point (remember NaN) and (surprisingly) not slower.

o   How should a user-defined == be found? There were two alternatives: Use “ordinary, traditional C++ lookup” (N4532) and “Make sure that == is always unique for a type”. The latter proposal (mine) was voted down for being “unusual and complex”. I was somewhat annoyed because I insist that x==y is either always true or always false (wherever you are in a program) when the values x and y doesn’t change. The other proposal then got itself tangled up in complexities because you can get different results of x==y in different namespaces:

X x = 1;

X y = 1;
//

namespace N {
    bool operator==(X,X) { return true; }
    bool b = (x==y);   // true
}
namespace M {
    bool operator==(X,X) { return false; }
    bool b = (x==y);   // false
}

This does violence to any reasonable idea of equality. I will bring up that issue again at the next meeting. Then, I should be much better prepared.

  • Capture *this in lambdas (P0018R0). In a lambda, we can easily capture the this pointer, but that’s not the whole *this object and that’s what we need for concurrent uses. EWG likes the idea, but suggested the proposal author look for a better syntax.
  • noexcept is now part of the type system (N4533). I think that is a mistake, but I was voted down. People will find creative ways to misuse this, and I see few benefits.
  • Defaults for fold() (P0036R0). EWG voted to remove the defaults for fold() because some were surprising and others were wrong for some types. The committee as a whole rejected that decision, so now we have time to find a proper solution, which is likely to involve concepts. I did not politic against EWG’s decision in full committee. I would have considered that disloyal, but someone else didn’t like that decision and got it reversed, leaving the working paper unchanged.
  • Coroutines (P0057R0, P0054R0). Stackless coroutines were added at the previous meeting. We discussed feedback and suggestions for improvement, and made a few. We also discussed stackfull coroutines (P0073R0) but did not reach a conclusion about those. We use the new keywords co_await, co_yield, and co_return. Plain await, yield, and return would have been prettier, but yield in particular would have clashed with a lot of function and variable names. We rejected a proposal to solve keyword clashes in general through a scope mechanism (P0056R0); that proposal would have led to chaos. Now we can write coroutines like

// recursive generator:

auto flatten(node* n) -> recursive_generator<decltype(n->value)>
{

    if (n != nullptr) {
        co_yield flatten(n->left);
        co_yield n->value;
        co_yield flatten(n->right);
    }
}

Each call will return the next node; the position in the tree is represented as the state of the coroutine. This will ship in Microsoft C++ soon (or maybe it is already shipping). These coroutines are blindingly fast (P0054R0 ; equivalent to function call/return).

  • Operator dot (N4477). At the last meeting, EWG approved a simple way of defining operator . (dot) in a way similar to how we define an operator ->. The idea is to support “smart references” in a manner similar to the way we support “smart pointers.” This time, we looked at an alternative (or additional) proposal to allow essentially arbitrary code to be executed based on the object and the member used (P0060R0). This could cause a scary amount of template metaprogramming to be executed for every object reference. That worried many (including me). Others wanted operator dot to support reflection and opposed because the proposal was too conservative. I was relieved to see that proposal rejected; it was too clever and opened too many ways of introducing hard-to-find bugs. Amazing stuff, though.
  • Structured bindings (D0144R0). H. Sutter, B. Stroustrup, and G. Dos Reis proposed a way of breaking out public date members of a class into local variables:

tuple<T1,T2,T3> f(/*...*/) { /*...*/ return {a,b,c}; }

auto {x,y,z} = f();               // x has type T1, y has type T2, z has type T3

The auto {x,y,z} introduces three new variables of the types of the corresponding class members. The EWG insisted that this should be done without compromising copy elision and with a protocol to allow values to be extracted from user-defined types. I agree wholeheartedly. That was the plan. Also, they wanted us to explore the possibility of optionally adding a type for an introduced variable. For example:

auto {x,string y,z} = f();       // x has type T1, y has type string, z has type T3

The point being that there are many examples of a C-style string being returned and needing conversion to string.

The proposal was accepted by acclamation! That never happens at first try smile. There will be a paper in the post-Kona mailing (see the WG21 site). So it seems that C++ will get a very general form of multiple return values. The fact that this looks a bit like simple pattern matching was of course noted.

Why bother with such a “little detail”? Shouldn’t we be concentrating on grand schemes and deep theoretical issues? “Structured decomposition” give us a little convenience, but convenience is pleasant and expressing things concisely is an important consideration. Also, what are the alternatives? We could write:

auto t = f();

auto x = get<1>(t);

auto y = get<2>(t);

auto z = get<3>(t);

In comparison, that’s verbose (four times the size!) and potentially inefficient. Also, the concern that provided the motivation to “clean up” multiple return values now was examples like this:

int x;

string y;

double z;

//

tie(x,y,z) = f();

Again (for a suitable definition of f()), this code is roughly equivalent to the example of structured binding. However, here we see one of the very last reasons to use uninitialized variables and also a default initialization of a string followed by an assignment (i.e., redundant overhead). Eliminating uninitialized variables (with their associated error opportunities) and eliminating redundant (and their associated temptations for low-level performance hacks) are part of a grander scheme of things. Details can be important.

  • Unified call syntax (N4474, P0131R0). Based on the discussion of problems and alternatives in P0131R0, half of the proposal was accepted: a call f(x) will find x.f() if there is no freestanding function that can handle f(x). The other way, x.f() to f(x), will not be accepted for now; we will revisit that once we have modules. We can now write simplified generic code and avoid duplication as long as we use the f(x) syntax (as we do in the STL). This becomes more important as we formalized good practices using concepts.

The reason to reject finding f(x) from x.f() was fear of getting instable interfaces. I consider that an unreasonable fear based on fear of overloading (see P0131R0), but many in EWG thought otherwise. The extension methods proposal (P0079R0) was rejected; many thought decorating functions to make them callable was ugly, special purpose, and backwards. We may be able to do better with modules.

Note that we don’t approve proposals by simple majority, we aim for consensus and consensus is defined as a very large majority (3-to-1 would be marginal). The alternative would be for a large angry minority to lobby against an “agreed upon” decisions and/or creating dialects. Consensus is essential for long-term stability.

  • Order of evaluation (P0145R0): We accepted a proposal from Gabriel Dos Reis to fix order of evaluation to left-to-right, except for assignment which is done right-to-left. Note that assignment also binds opposite to all other operations – it was always special. Consider my example from TC++PL4:

void f()
{

    std::string s = “but I have heard it works even if you don’t believe in it”;
    s.replace(0, 4, “”).replace(s.find(“even”), 4, “only”).replace(s.find(“ don’t”), 6, “”);
    assert(s == “I have heard it works only if you believe in it”);
}

It looks sensible until you realize that under the old C and C++ rules its meaning is undefined. Oops! Some compilers generate code that violates the expectations vis a vis chaining.

Here is another (more recent example):

#include <map>
int main()
{
    std::map<int, int> m;
    m[0] = m.size();
}

Under the new rules, this works. Now, why doesn’t it work today? Might you have something like that in your code today?

Performance was a concern: will performance suffer? It will for some older machine architectures (1% was mentioned), but there can be backwards compatibility switches and performance-sensitive applications have mostly moved to architectures where there is no performance degradation years ago.

This proposal was accepted.

  • inline variables (N4424). The proposal to accept “inline variables” analogous to inline functions was accepted at the previous meeting (Lenexa, Kansas) partly because I was out of the room on different business when the discussion started. I was shocked: among other things, it would make it easier to use of global variables by hiding them in header files. In Kona, we decided to limit the inline mechanism to global constants (Phew!).
  • constexpr lambdas (N4487). We can now use a lambda in a constant expression provided the lambda’s body can be constexpr.
  • constexpr_if (P0128R0). We will be able to use a compile-time if to express alternatives within a function body as long as it affects a single scope only:

template <class T, class... Args>
unique_ptr<T> make_unique(Args&&... args)
{
    constexpr_if (is_constructible_v<T, Args...>) {

        return unique_ptr<T>(new T(forward<Args>(args)...));
    }
    constexpr_else {
        return unique_ptr<T>(new T{forward<Args>(args)...});
    }
}

This proposal doesn’t mess with scope rules or AST-based compilation models the way earlier proposals for compile-time selection had.

  • Guaranteed copy elision (P0135R0). We can now rely on copy elision. Until now, it has been simply a common optimization.
  • Making void a normal type (P0146R0). Making void a type like other type is an attractive proposition because it eliminates many special cases and simplifies generic programming (by eliminating the need to specialize for void), Unfortunately, to match existing semantics, maintain ABI compatibility, and maintain C compatibility, making void “ordinary” requires almost as many special cases as we currently have. So the proposal was rejected.
  • Aggregate initialization of derived classes (P0017R0). A public base class can now be initialized like a member using the list initialization syntax.

struct base { int bm; };

struct derived : base { int m; };

derived d {42,43}; // bm==42, m=43

This reflects the view that a base is an unnamed member (e.g., see the ARM (1989)).

  • Template parameter deduction for constructors (P0091R0). I don’t know if you like to write “make functions” so that you can deduce a class type from a set of arguments. For example:

f(make_pair(“foo”s,12)); // make a pair<string,int> and pass it to f()

I don’t, but the alternative has up until now been worse:

pair<string,int> x = { “foo”s,12 };

f(x);

C++17 will allow

f(pair{“foo”s,12});

and

pair y {“foo”s,12};

This is a general deduction mechanism, rather than something just for std::pair. The template arguments for the constructor is simply chosen exactly as for a make function. This removes boilerplate.

  • [[fallthrough]], [[unused]], [[nodiscard]] (P0068R0). We will be able to explicitly mark a fall through from one case to another:

switch (n) {
case 22:
case 33:                // OK: no statements between case labels
    f();
case 44:                // WARNING: no fallthrough statement
    g();
    [[fallthrough]];
case 55:                // OK
    //
}

This should save us from nasty bugs and improve warning messages. Similarly, the attributes [[unused]] and [[nodiscard]] can make assumptions accessible to compilers and analysis tools. I have my doubts about the utility of those last two attributes outside C-style code, but experienced people disagree. [[unused]] may be renamed [[maybe_unused]]; there is a “bikeshed discussion” about that name. Naming is always hard.

I have listed under half of the proposals considered by EWG. Most (probably all) of the rest were rejected.

Problems

There has been no work on a stack_array (a standard-library type with its elements guaranteed to be on the stack). This forces people who want to place arrays on the stack to use alloca() or other non-standard facilities. As stack allocation is becoming increasingly important because of caches and concurrency, that’s rather bad. Also, we are assured that progress is made on compile-time reflection in SG7, but I fear that nothing will be ready for C++17.

Note that there are TSs for good proposals that don’t make C++17, and after that, there is C++20.

More

There will be other trip reports. Here are some early ones:

The next WG21 meetings:

  • 2016

o   Jacksonville, Florida; Feb 29 – (Perennial and Foundation)

o   Oulu, Finland; June 20 – (Symbio). The C++17 feature set should be fixed here.

o   Oklahoma (most likely); October

  • 2017

o   San Diego (most likely); January or February

o   “London”; June or July – (Morgan Stanley?). Vote out C++17! (if all goes well).

o   Somewhere in the US; November

Summary

We seem to be on track to deliver C++17 on time as an exciting and extremely useful new standard. I have reason to believe that C++17 will be a step up of the magnitude of the step from C++98 to C++11, but easier to make because of improved work on compatibility and usability. For those of you that are not even at C++11, get there ASAP for correctness, productivity, performance, and fun, but also because C++11 will get you most of the way to C++14 and C++17.

Summary of the features (discussed in this meeting) that I consider most significant:

  • Concepts
  • Modules
  • Parallelism TS
  • Ranges TS
  • Concurrency TS
  • Contracts
  • Coroutines
  • Order of evaluation
  • Uniform function call syntax
  • variant, array_view, and string_view
  • Structured bindings (simpler handling of multiple return values)
  • [[fallthrough]]

I’m sure that most of the time was spent on “other”. That’s important too, but I can’t describe everything without boring all.

You can compare that to the top-ten list I made about a year ago (“Thoughts about C++17”, N4492):

  • Concepts (they allows us to precisely specify our generic programs and address the most vocal complaints about the quality of error messages)
  • Modules (provided they can demonstrate significant isolation from macros and a significant improvement in compile times)
  • Ranges and other key STL components using concepts (to improve error messages for mainstream users and improved the precision of the library specification “STL2”)
  • Uniform call syntax (to simplify the specification and use of template libraries)
  • Co-routines (should be very fast and simple)
  • Networking support (based on the asio in the TS)
  • Contracts (not necessarily used in the C++17 library specification)
  • SIMD vector and parallel algorithms (to better target modern hardware)
  • Library “vocabulary types”, such as optional, variant, string_view, and array_view
  • A stack_array for getting arrays on the stack

Given that nobody can expect to get exactly what they want, we seem to be on track.

So, what is the big picture? What are we really trying to do? N4492 is my answer – the only answer I have seen articulated:

  • Improve support for large-scale dependable software
  • Provide support for higher-level concurrency models
  • Simplify core language use, especially as it relates to the STL and concurrency, and address major sources of errors.

That paper provides details.

The C++ Core Guidelines effort (https://channel9.msdn.com/Events/CPP/CppCon-2015/Writing-Good-C-14 , https://channel9.msdn.com/Events/CPP/CppCon-2015/Writing-Good-C14-By-Default ) is an attempt to set a direction that can lead us from today’s “legacy” code to the envisioned future. For starters, we offer a promise of no dangling pointers and no resource leaks (guaranteed).