Trip Report: August 2010 ISO C++ Standards Meeting

ISO C++ committee in Rapperswil, Switzerland
WG21 in Rapperswil, Switzerland

The summer 2010 ISO C++ meeting was held on August 2-7 in Rapperswil, Switzerland. The post-meeting mailing is now live, including meeting minutes and other information.

In March (trip report), we voted the last set of feature changes into a Final Committee Draft (FCD) and, after two weeks of scurrying to apply the changes, the result was balloted among ISO national bodies from Mar 27 through Jul 27. That means we received the ballot results and ~250 pages of comments just in time for the start of this meeting, and have busied ourselves with starting to process them.

Where are we in the process?

For this and the next couple of meetings (Batavia IL in November, and Madrid in March), the committee is doing ballot resolution and dealing with national body comments. Because we issued a Final Committee Draft, ISO C++0x can officially no longer add new features. All that we can do is address national body comments, and make any other bug fixes we find.

The good news is that comment volume and content is considerably lighter than the comments on the CD ballot, and we expect to be able to finish handling all of them in two more meetings and, barring any surprises, vote on the Final Draft International Standard (FDIS) for C++0x standard after the Madrid meeting in March. If that happens and that ballot succeeds, the C++0x standard will be published in 2011 and we can start truthfully calling it C++11 and stop pretending about the ‘0’.

Low probability contingency: If between now and Madrid something unforeseen arises and we feel the standard is not in good enough shape to ship and needs more work, the fallback route would be to instead issue a second Final Committee Draft (FCD), which adds another comment cycle and another year to the overall process. We hope that won’t be necessary.

What did we do at this meeting?

In Rapperswil, the Core, Library, and Concurrency subgroups spent the week triaging the comments and beginning to resolve the biggest or most potentially controversial questions first.

We accomplished a lot. Here are the key decisions, some of them tentative:

Attributes: alignment, noreturn, and virtual control. My biggest (but not only) beef with C++0x [[attributes]] is that the standard itself was abusing attributes as disguised [[keywords]]. Attributes are acceptable as pure annotations, but they should have no semantic effect on the program. The problem was that some C++0x attributes did have such an effect, notably the virtual control attributes, so I’ll start with those.

My personal hot button for this meeting was that C++0x not look like the following example, which is taken almost verbatim out of the FCD ballot draft. The semantics are excellent and desirable, but the syntax is clearly not what anyone would design in a fresh programming language:

class [[base_check]] Derived : public Base {
public:
  virtual void f [[override]] ();
  virtual double g [[final]] ( int );
  virtual void h [[hiding]] ();
};

The road to the above was paved with good intentions. But it’s a clear example of adding language keywords dressed in attributes’ clothing, and not something I want to be responsible for forcing three million C++ developers to live with until the end of time.

Fortunately, the committee has tentatively agreed and decided to pursue replacing these attributes with keywords. For the next meeting, I and several other experts volunteered to write a concrete change proposal paper on this, and will include a description of two categories of options:

  • fully reserved words, which can break existing user code that uses the words as variable or type names and so would mean we need to pick uglier names; and
  • contextual keywords as done in C++/CLI, which does not break existing user code and so lets us pick the ideal nice names, but which would be the first contextual keywords in ISO C++ (and there’s always resistance to being the first).

This week’s straw poll sentiment favored fully reserved keywords over contextual keywords, but both had stronger support than attributes.

The other two kinds of attributes that we considered changing to keywords were [[align]] to specify the alignment of a type, and [[noreturn]] to specify that a function never return. We decided to pursue changing [[align]] to a keyword, and leaving [[noreturn]] alone.

noexcept, part 1: Destructors noexcept by default. This is a tentative resolution to be written up and voted on at the next or following meeting. To me, this is an important achievement, because we have always taught people never to throw from destructors (see Exceptional C++ Item 16, subtitled “Destructors That Throw and Why They’re Evil”) and now the language will enforce that at least by default.

Background: Why are throwing destructor bad? Because any type with a destructor that could throw is inherently unsafe to use nearly all the time. Any type whose destructor could throw is already banned from use with the standard library (i.e., can’t be put in a container or passed to an algorithm), cannot be reliably used as a class data member (because if while constructing the containing object another class data member throws an exception, and then as the destructors of the already-constructed members are called this member’s destructor throws an exception, the can’t-have-two-active-exceptions rule kicks in and the program terminates immediately), and cannot even be reliably used as an array (because if while constructing the array one constructor throws an exception, and then as we call the destructors of the already-constructed objects one of those throws an exception, the can’t-have-two-active-exceptions rule kicks in and the program terminates immediately).

We acknowledged that this change will break some code by making it call terminate. We (not quite unanimously) agreed that such code not only deserves to be broken, but in fact is already broken in a less obvious way; for some examples, see GotW #47. Granted, we know that a small but steady trickle of developers have regularly tried to be clever, claiming they have legitimate uses for a throwing destructor. I’ve seen a number of such claims, and they’ve always turned out to be bad, unsafe code. This change will do the world a favor by making such code terminate deterministically at test time the first time you try to execute it.

If someone really truly feels they are an exception, that’s fine, they are allowed to write “noexcept(false)” on their destructor. Personally, though, I’d recommend that companies consider automatically rejecting attempts to check in any C++ source file containing that string.

no except, part 2: noexcept will be applied to the standard library. This also is important. At our previous meeting, we voted noexcept into the language (and deprecated exception specifications) but didn’t yet have time to apply noexcept to the standard library (which was still using exception specifications, and it’s odd for the standard to keep using a deprecated feature). That will now be done.

First, all empty exception specifications (which is all of them), currently spelled “throw()”, will be replaced with “noexcept”.

Second, all standard library functions whose description include “Throws: Nothing” will be changed to “noexcept”. This is an even bigger improvement, because it changes normative documentation/commentary into actual normative code.

Third, an analysis will be done of all move constructors used in the standard library, and we’ll see if all of those can also be changed to “noexcept”. That analysis will be reviewed at a future meeting and a course of action on this decided there.

noexcept, part 3: terminate stays. It was reaffirmed that if you violate a noexcept specification, your program will call std::terminate and not continue execution in what would be a corrupt state. Stack unwinding is not required.

Looking forward

Finally, here are the scheduled dates and locations for the next few ISO C++ standards committee meetings:

Herb

Effective Concurrency: Prefer Using Futures or Callbacks to Communicate Asynchronous Results

This month’s Effective Concurrency column, “Prefer Using Futures or Callbacks to Communicate Asynchronous Results,” is now live on DDJ’s website.

From the article:

This time, we’ll answer the following questions: How should we express return values and out parameters from an asynchronous function, including an active object method? How should we give back multiple partial results, such as partial computations or even just “percent done” progress information? Which mechanisms are suited to callers that want to “pull” results, as opposed to having the callee “push” the results back proactively? And how can “pull” be converted to “push” when we need it? Let’s dig in…

I hope you enjoy it. Finally, here are links to previous Effective Concurrency columns:

The Pillars of Concurrency (Aug 2007)

How Much Scalability Do You Have or Need? (Sep 2007)

Use Critical Sections (Preferably Locks) to Eliminate Races (Oct 2007)

Apply Critical Sections Consistently (Nov 2007)

Avoid Calling Unknown Code While Inside a Critical Section (Dec 2007)

Use Lock Hierarchies to Avoid Deadlock (Jan 2008)

Break Amdahl’s Law! (Feb 2008)

Going Superlinear (Mar 2008)

Super Linearity and the Bigger Machine (Apr 2008)

10 Interrupt Politely (May 2008)

11 Maximize Locality, Minimize Contention (Jun 2008)

12 Choose Concurrency-Friendly Data Structures (Jul 2008)

13 The Many Faces of Deadlock (Aug 2008)

14 Lock-Free Code: A False Sense of Security (Sep 2008)

15 Writing Lock-Free Code: A Corrected Queue (Oct 2008)

16 Writing a Generalized Concurrent Queue (Nov 2008)

17 Understanding Parallel Performance (Dec 2008)

18 Measuring Parallel Performance: Optimizing a Concurrent Queue(Jan 2009)

19 volatile vs. volatile (Feb 2009)

20 Sharing Is the Root of All Contention (Mar 2009)

21 Use Threads Correctly = Isolation + Asynchronous Messages (Apr 2009)

22 Use Thread Pools Correctly: Keep Tasks Short and Nonblocking(Apr 2009)

23 Eliminate False Sharing (May 2009)

24 Break Up and Interleave Work to Keep Threads Responsive (Jun 2009)

25 The Power of “In Progress” (Jul 2009)

26 Design for Manycore Systems (Aug 2009)

27 Avoid Exposing Concurrency – Hide It Inside Synchronous Methods (Oct 2009)

28 Prefer structured lifetimes – local, nested, bounded, deterministic(Nov 2009)

29 Prefer Futures to Baked-In “Async APIs” (Jan 2010)

30 Associate Mutexes with Data to Prevent Races (May 2010)

31 Prefer Using Active Objects Instead of Naked Threads (June 2010)

32 Prefer Using Futures or Callbacks to Communicate Asynchronous Results (August 2010)