ISO C++0x: Complete Public Review Draft In October 2007?

You might say that it looks like "x might not be hex."

I’m happy to report that work on "C++0x", the much-anticipated Version 2.0 of the ISO C++ standard, has dramatically picked up steam over the past few months. The ISO C++ committee has now published the first partial draft of C++0x (for what "partial" means and what’s still missing, see below), and plans to publish a complete public draft before the end of 2007.

In this article I’ll give a quick history of the C++ standard and the current expected timeline. I’ll also summarize (drum roll please) which major features the committee decided to put in C++0x and the features that didn’t make the cut. In the coming months, I’ll go into more detail about these major features as they gel.

From C++98 until now: The story so far

It’s hard to believe it’s been nearly a decade since my first "C++ State of the Union" article appeared in C++ Report. That article, which I wrote on the way home from the July 1997 C++ standards meeting, anticipated correctly that the committee would manage to work through their large bug backlog and vote out a final Draft International Standard at the November 1997 meeting. That they did, to much cheering and fanfare and even a press conference from the main committee room, despite some last-minute excitement involving auto_ptr. ISO took its usual 6-12 months to process red tape, and the first edition of ISO Standard C++ was published in 1998 (aka C++98).

After 1997, the committee deliberately slowed down so as to give the compilers time to catch up to the many innovations in the standard. We’ve been meeting only two (not three) times a year, and from 1998-2003 we limited ourselves to just processing defect reports (bug fixes and requests for clarification) and no new features, to keep the standard stable. In 2002, we finally produced "service pack 1" of the C++ standard, which was published in 2003 (aka C++03).

Then the gates reopened and "C++0x" got underway. New features have been under serious development since 2003-4, and the committee has long had a target of publishing the next C++ standard by the end of the decade; that’s why it has been called "C++0x". (If that schedule fails, we can always make the awkward joke that it’s still C++0x, only x is a hexadecimal number, ha ha. But we’d rather finish on time.)

About C++0x

ISO C++ timeline proposals, October 2006

C++0x target timeline

At the most recent ISO C++ meeting, in October 2006, we considered two main timeline options. They are pictured at right, in a copy of a slide I showed during that meeting to spur discussion. In the first option, we actually publish in 2009 and legitimately get to be called "C++09". In the second, we finish the document in 2009, but because ISO takes most of a year to approve and publish a standard, it would end up as "C++10" (or, one could uncomfortably imagine, "C++0a").

The committee wrung its collective hands, and decided to put in overtime to make the first path happen. Working backward, the dates that need to be hit are:

  • 2009: Publish "ISO/IEC 14883(2009): Programming Language C++"
  • October 2008 ISO C++ meeting: Complete the final text of C++0x and vote it out for balloting, having crossed all the t’s and dotted all the i’s, and in particular having addressed all public comments received during the public review period.
  • October 2007 ISO C++ meeting: Complete the first complete draft of C++0x and vote it out for public review and comments.

Given the work that remains, this means meeting more frequently than we’ve been doing for the past decade. For 2007, the committee agreed to let me put it back on a three-full-meetings schedule, and so for the first time since 1997 we’re having a July meeting. On top of that, subgroups have been organizing additional smaller meetings in between on specific topics, such as concepts. I’ll summarize the meeting schedule at the end of this article.

What’s in C++0x

You can get a very good feel for the contents of C++0x by looking at the first partial draft mentioned above. That draft contains the bulk of the extensions the committee pulled in from the first C++ Standard Library Extensions Technical Report (TR1). It does not, however, contain text for all major features yet, and has placeholders for the major features that I’ll summarize in this section.

Barring a disaster, here are the following additional major features not yet in the above partial draft that will be in C++0x. Every bullet heading links to a good "read this first" paper about the feature, and for some I’ve included additional links.

Concepts [N2081]

From that paper:

"Concepts introduce a type system for templates that makes templates easier to use and easier to write. By checking the requirements that templates place on their parameters prior to template instantiation, concepts can eliminate the spectacularly poor error messages produced by today’s template libraries, making them easier to use. … At the core of concepts is the idea of separate type checking for templates. Template declarations are augmented with a set of constraints (requirements): if the definition of the template typechecks against these requirements, and a use of a template meets these requirements, then the template should not fail to instantiate."

Imagine, if you will, an error message like ‘sorry, YourType isn’t a BidirectionalIterator’ instead of three pages of arcane messages about what templates couldn’t be instantiated. Among other things, concepts will let us write the standard’s own container and iterator requirements in code, rather than as English "cookbooks" of programming conventions.

The concepts proposal is coauthored by Bjarne Stroustrup and Doug Gregor. You can already start trying them out: There is a ConceptGCC proof-of-concept implementation that covers most of the proposal. For more details about how concepts can be applied to the C++ standard library, see also papers N2082, N2083, N2084, and N2085.

Garbage collection [N2129]

A C++0x compiler must provide garbage collection, which the programmer can use on request; "don’t GC this region of code" is still the default. This "opt-in" model leaves existing programs’ semantics unchanged, while providing real GC support for
programs that want it. It is also intended to enable garbage collection for objects allocated and manipulated by most legacy libraries, which both makes it much easier to convert existing code to a garbage-collected environment and helps "repair" legacy code with deficient memory management. Of course, any C++98/03/0x compiler is already free to garbage-collect the whole C++ heap, and a number of current implementations do that; but they aren’t required to do so, and this change would require GC to be available in a way that programmers can use and rely on. This work has been primarily driven by Hans Boehm and Mike Spertus. You can find a detailed paper here: N2128.

Memory model for concurrency [N2138]

As I wrote in "The Free Lunch Is Over", chip designers and compiler writers "are under so much pressure to deliver ever-faster CPUs that they’ll risk changing the meaning of your program, and possibly break it, in order to make it run faster." This only gets worse in the presence of multiple cores and processors.

A memory model is probably of the lowest-level treaty between programmers and would-be optimizers, and fundamental for any higher-level concurrency work. Quoting from my memory model paper: "A memory model describes (a) how memory reads and writes may be executed by a processor relative to their program order, and (b) how writes by one processor may become visible to other processors. Both aspects affect the valid optimizations that can be performed by compilers, physical processors, and caches, and therefore a key role of the memory model is to define the tradeoff between programmability (stronger guarantees for programmers) and performance (greater flexibility for reordering program memory operations)." This work is being driven primary by Hans Boehm, Clark Nelson, and myself.

Concurrency libraries [N2094]

The committee will likely release the concurrency libraries in two parts, both of which are likely to be released at about the same time.

  • In C++0x itself: Support at the level of basic threads and locks, as well as atomic operations for lock-free coding, and related features like thread local storage.
  • In the second C++ Standard Library Extensions Technical Report (aka Library TR2): More advanced extensions including futures and upgradable locks, so that we can gain experience with them before considering them for the standard itself post-C++0x. This follows the same path the committee took with the first set of library extensions, including shard_ptr and the hash-based containers: Those were first put into a separate TR (TR1), completed in 2004, and then based on experience most TR1 features were voted into the standard itself in April 2006 so that they are now part of the current partial draft of C++0x. The TR2 features are planned to be on a similar path, but for now are being released as a separate specification and not part of C++0x.

For more information and snapshots of current draft proposals still under discussion and development, see: N1907, N1966N2047, and N2090.

What’s not in C++0x

The following major features were cut from C++0x because they require more work and would delay the next standard. Once C++0x is done, the committee may pick them up again.

Modules [N2073]

It’s definitely desirable to have a module system for C++ to package libraries and their implementations, and to provide an alternative to C++’s current build model based on textual source file inclusion. Reliance the current source file inclusion model poses technical difficulties for large C++ programs, notably: (a) long build times for large projects; and (b) difficulty of managing dependencies between interfaces and implementations. The current work has been spearheaded primarily by Daveed Vandevoorde (of EDG fame). The committee still intends to do work on this, but it’s now planned as a separate Technical Report on Modules after C++0x is complete rather than as part of the C++ standard.

Dynamic libraries [N1496]

Although C++ programmers routinely use shared libraries in C++ today, the C++ standard doesn’t specify their semantics in a portable way. Indeed, there are some fundamental semantic differences between some popular approaches, such as between Windows static and dynamic libraries and Linux shared libraries. Note that C++’s broad cross-platform support, and the existence of many existing approaches on those different platforms, makes it more difficult to specify portable library semantics than in languages like Java that started fresh with their own (then-new) run-time environment. Several committee members, notably Pete Becker, have done work to try to reconcile the existing approaches in a standard way that implementers could broadly support, but this effort will not be ready in time for C++0x.

Next Steps

Here’s the current list of 2007 meetings, with the "extra" meetings and milestones bolded:

  • Jan 22-24, Batavia, IL, USA: Ad-hoc subgroup meeting on library working group issue cleanup.
  • Feb 22-23, Mountain View, CA, USA: Ad-hoc subgroup meeting on concepts.
  • Apr 15-20, Oxford, UK: Full WG21/J16 spring meeting.
  • Jul 15-20, Toronto, Canada: Full WG21/J16 extra meeting.
  • Sep 29 – Oct 6, Kona, HI, USA: Full WG21/J16 fall meeting. (Extended to Saturday.)
    Goal: Vote out the first complete public review draft of C++0x on Oct 6.

The extra meetings exist specifically to reach the goal of having that full draft before the end of this year. We’ll know as we get closer how well the working paper is coming together.

Regardless of when the first public review draft is published, don’t expect it to be the final text: The draft is to get a round of public comments, and we know there will be issues to refine and tweak over the following year. But that first complete public draft will contain standardese for all major C++0x features in near-final form, which is quite a milestone (and quite a mouthful). It will give us the first real and concrete look at the shape of C++0x.

Over the coming months I’ll be posting additional articles about specific features in the new standard, including some of the cool new features mentioned above. Stay tuned.

Wozniak on Apple

Here’s a wonderful interview with The Other Steve (Wozniak) on the start of Apple. It’s part of a new book called Founders At Work, full of similar interviews with all sorts of well-known founders of companies/products from Adobe and Lotus to TiVo and Ruby on Rails. (I don’t have any commercial interest in the book; I just heard about it via the blogosphere.)

Fair warning: It’s a long interview. But it’s fascinating. Here’s a small excerpt that resonates strongly with me in our highly complexified world of deeply layered and arbitrarily composed software, where programmers are all too often insulated from knowing the true cost of something as simple as a library call:

Livingston: What is the key to excellence for an engineer?

Wozniak: You have to be very diligent. You have to check every little detail. You have to be so careful that you haven’t left something out. You have to think harder and deeper than you normally would. It’s hard with today’s large, huge programs.

I was partly hardware and partly software, but, I’ll tell you, I wrote an awful lot of software by hand (I still have the copies that are handwritten) and all of that went into the Apple II. Every byte that went into the Apple II, it had so many different mathematical routines, graphics routines, computer languages, emulators of other machines, ways to slip your code in and out of an emulation mode. It had all these kinds of things and not one bug ever found. Not one bug in the hardware, not one bug in the software. And you just can’t find a product like that nowadays. But, you see, I had it so intense in my head, and the reason for that was largely because it was part of me. Everything in there had to be so important to me. This computer was me. And everything had to be as perfect as could be made. And I had a lot going against me because I didn’t have a computer to compile my code, my software.

Questions About Exception Specifications

In the past few days, I’ve had several people independently send me email to ask related questions about exception specifications. That must be reason enough to echo some answers here.

Background

For background, here are two places where I’ve written about exception specifications:

I’ve taken the liberty of pasting the entire latter reference at the bottom of this post. Enjoy!

Now on to Question the First…

Q1: How can you know you’ve caught everything if you don’t use exception specifications?

Andrew Skypeck asked:

In CCS#75 you suggest that one ought not provide an exception specifications with functions. Without them, how can a user of the function be certain they have caught all possible exceptions without inspecting the code they are calling? This is often not possible for API users that have header files only.

Two thoughts:

First, the way to catch everything is to catch(…), and that always works. You seem to be wanting to use exception specifications as documentation (which is fine), and so you can get the same ability by writing the exception specification as a comment. Note that even if you try to write them all as actual code, you can’t do it in general — notably you can’t do it for templates, because if a template can be instantiated with any type, you generally can’t know in advance what it might throw.

Second, the caller of a function doesn’t always need to catch all possible exceptions; it should only catch the exceptions that it knows how to handle (or translate). Exception safety is not just about making sure that the code that knows how to detect an error throws, and that the code that knows how to handle the error catches; rather, in practice exception safety is largely about making sure the code in between stays out of the way, including that it doesn’t catch and absorb exceptions. For more about this aspect of exception safety, start with these Items in C++ Coding Standards, and follow the references at the end of each Item to dig into the details that interest you:

  • 70. Distinguish between errors and non-errors.
  • 71. Design and write error-safe code.
  • 72. Prefer to use exceptions to report errors.
  • 74. Report, handle, and translate errors appropriately.

Which brings us to Question the Second:

Q2: Why not statically enforce exception specifications?

Bob Rossi asked, while kindly citing the above article:

I would like to know what the possibilities are of C++0x enforcing the exception specifications like Java does. Here is a good article describing why exception specifications acting the way they do are currently bad, http://www.gotw.ca/publications/mill22.htm

I must not fully understand the situation. What is wrong with the compiler time checks that Java does to enforce the exception specifications? I find this feature extremely useful as a developer!

The short answer is that nobody knows how to fix exception specifications in any language, because the dynamic enforcement C++ chose has only different (not greater or fewer) problems than the static enforcement Java chose.

If you’re interested in reading more about this, try googling for newsgroup postings, http://groups.google.com/groups?q=sutter+exception+specifications. The following is taken from the second hit, which I wrote last fall:

Essentially, exception specifications are a wonderful idea in basic principle, but no one really knows how to design them.

There are two major approaches, and both have serious problems. Java chose static enforcement (at compile time, as suggested above), and C++ chose dynamic enforcement. Interestingly, I see Java people ask "why not enforce these dynamically?" about as often as I see C++ people ask "why not enforce these statically?"

Briefly:

When you go down the Java path, people love exception specifications until they find themselves all too often encouraged, or even forced, to add throws Exception, which immediately renders the exception specification entirely meaningless. (Example: Imagine writing a Java generic that manipulates an arbitrary type T…)

When you go down the C++ path, people love exception specifications until they discover that violating one means invoking terminate, which is almost never what you want.

So why did C++ do exception specifications the way it did, with dynamic enforcement via terminate? And why did Java do it the other way? In both cases, it seemed like a good idea that avoided some set of known problems, and you can’t always know the new problems you incur instead until you gain experience with multiple releases of large code bases, which means over time.

The future of exception specifications?

Bob responded by asking why we don’t just fix exception specifications, or remove them entirely until something better comes along. Those are good questions.

Taking the latter part first: As tempting as it may be, one can’t just rip out a language feature because one decides it isn’t working out quite right. The primary reason is that there are people using the feature, and breaking existing legal code is, well, rude.

What about fixing exception specifications? That would be nice, and I think nearly everyone I know is willing to consider changing them, but only if: (a) there is a well-understood replacement (there isn’t today), and (b) there was a good way to deal with migration from existing code which may rely on the existing feature.

Deliberate change with a strong dose of backward compatibility is always the key. This one needs more deliberation, at least for now, and isn’t expected to change in C++0x.

Epilogue: C++CS Item 75

I’m sure Addison-Wesley won’t mind overmuch if I paste one Item here in its entirety. It has been slightly reformatted for the web.

75. Avoid exception specifications.

Summary

Take exception to these specifications: Don’t write exception specifications on your functions unless you’re forced to (because other code you can’t change has already introduced them; see Exceptions).

Discussion

In brief, don’t bother with exception specifications. Even experts don’t bother. The main problems with exception specifications are that they’re only “sort of” part of the type system, they don’t do what most people think, and you almost always don’t want what they actually do.

Exception specifications aren’t part of a function’s type, except when they are. They form a shadow type system whereby writing an exception specification is variously:

  • Illegal: In a typedef for a pointer to function.
  • Allowed: In the identical code without the typedef.
  • Required: In the declaration of a virtual function that overrides a base class virtual function that has an exception specification.
  • Implicit and automatic: In the declaration of the constructors, assignment operators, and destructors when they are implicitly generated by the compiler.

A common but nevertheless incorrect belief is that exception specifications statically guarantee that functions will throw only listed exceptions (possibly none), and enable compiler optimizations based on that knowledge.

In fact, exception specifications actually do something slightly but fundamentally different: They cause the compiler to inject additional run-time overhead in the form of implicit try/catch blocks around the function body to enforce via run-time checking that the function does in fact emit only listed exceptions (possibly none), unless the compiler can statically prove that the exception specification can never be violated in which case it is free to optimize the checking away. And exception specifications can both enable and prevent further compiler optimizations (besides the inherent overhead already described); for example, some compilers refuse to inline functions that have exception specifications.

Worst of all, however, is that exception specifications are a blunt instrument: When violated, by default they immediately terminate your program. You can register an unexpected_handler, but it’s highly unlikely to help you much because you get exactly one global handler and the only way the handler could avoid immediately calling terminate would be to rethrow an exception that is permissible—but because you have only one handler for your whole application, it’s hard to see how it could do useful recovery or usefully know what exceptions might be legal without trivializing exception specifications altogether (e.g., following the discipline of having all exception specifications allow some general UnknownException eliminates any advantage that having an exception specification might have had in the first place).

You generally can’t write useful exception specifications for function templates anyway, because you generally can’t tell what exceptions the types they operate on might throw.

Paying a performance overhead in exchange for enforcements that are nearly always useless because they are fatal if they ever fire is an excellent example of a premature pessimization (see Item 9).

These is no easy fix for the problems described in this Item. In particular, the problems are not easily solved by switching to static checking. People often suggest switching from dynamically checked exception specifications to statically checked ones, as provided in Java and other languages. In short, that just trades one set of problems for another; users of languages with statically checked exception specifications seem to equally often suggest switching to dynamically checked ones.

Exceptions

If you have to override a base class virtual function that already has an exception spec­ifi­ca­tion (e.g., ahem, std::exception::what), and you don’t have the ability to change the class to remove the exception specifications (or to convince the class’s main­tainer to remove them), you will have to write a compatible exception specification on your overriding function, and you should prefer to make it no less restrictive than the base version so as to minimize the frequency with which it might be violated:

// in a class written by someone else,
// the author used an exception specification,
// and if you can’t get him to remove it…

class Base { // …
virtual f() throw( X, Y, Z );
};

// … then in your own class your override
// must have a compatible (and preferably
// the identical) exception specification
class MyDerived : public Base { // …
  virtual f() throw( X, Y, Z );
};

[BoostLRG]’s experience is that a throws-nothing exception specification (i.e., throw()) on a non-inline function “may have some benefit with some compilers.” Not a stunning endorsement from one of the most highly regarded and expertly designed C++ library projects in the world.

References [see the C++CS online bibliography for reference details and other links]

[BoostLRG] – [Stroustrup00] §14.1, §14.6 – [Sutter04] §13

“Why Are You Doing What You’re Doing?”

For nearly a decade, I’ve had a plaque bearing that question on my desk.

I think the question is valuable because it goes directly to motive. It’s also a deliciously contextual question — it means something different every minute, depending on what you’re up to. Here are a few scattered examples:

  • "Why am I doing this job?" Is it because someone, or society, told me that this was "success" (see last week’s Friday Thought)? Because it’s a way to make ends meet? Because I really enjoy it? Because this is a fun and cohesive team? Because I’m too tired to look for another job? Because I don’t think I could make it at a job I’d actually like to do?
  • "Why am I writing the code this way?" Is it because someone told me to, even though I don’t completely understand the reason? Because it’s the right way? Because I’m under time pressure and plan to fix it later? Because it’s a short cut and I don’t care about this product? Because I haven’t looked in Knuth’s classic The Art of Computer Programming to see if there’s already a known better structure or algorithm? Because I’m tired or distracted? Or because of something else?
  • "Why did I fail to show appreciation for a friend’s help?" Is it because I failed to realize how much they helped me, and at what cost to themselves? Because I was too absorbed/tired/stressed/distracted with just my own troubles? Because I care, but repeatedly failed to show it when it mattered? Because perhaps I actually do need to care more about other people and actively take an interest in them? Because of some combination of the above, and/or possibly more reasons?
  • "Why am I driving to the store?" Is it because that’s what everyone does? Because it’s what I’ve always done? Because I don’t have time to walk or bike (and if so, why not)? Because the groceries are too heavy/bulky to carry back? Because I haven’t thought of riding a bike in years?
  • Etc.

Nobody’s perfect. I’ve wrestled with these and other questions, as I’m sure you do too, and try to improve a little every day and every year.

Being intentional is more than just about programming. We can get there if we keep trying.

Channel 9 Interview: Software Composability and the Future of Languages

Last week, Anders Hejlsberg, Erik Meijer, Brian Beckman and I recorded an interview/chat that covered a range of topics related to programming and languages.

The video is now available online. Here’s the summary pasted from the Channel 9 site:

Software Composability and the Future of Languages
Anders Hejlsberg, Herb Sutter, Erik Meijer, Brian Beckman

How will imperative programming languages evolve to suit the needs of developers in the age of Concurrency and Composability? What role can programming languages play in enabling true composability? What are the implications of LINQ on the future of managed (CLS-based) and unmanaged(C++) languages? How will our imperative languages (static) become more functional (dynamic) in nature while preserving their static "experience" for developers?

Answers to these questions and much more are to be found in this interview with some of Microsoft’s leading language designers and programming thought leaders: Anders Hejlsberg, Technical Fellow and Chief Architect of C#, Herb Sutter, Architect in the C++ language design group, Erik Meijer, Architect in both VB.Net and C# language design and programming language guru, and Brian Beckman, physicist and programming language architect working on VB.Net.

This is a great conversation with some of the industry’s most influential programming language designers. Tune in. You may be surprised by what you learn…

Apologies in advance if the video doesn’t work for some combination of platforms and browsers.

Ichiro on Success

What does the word "success" mean to you? There’s no shortage of opinions about what Success should mean and upon which particular Altar of Success we ought to sacrifice our lives and energies. That doesn’t mean those opinions are worth paying attention to. As a quote attributed to Lily Tomlin put it nicely, ‘the trouble with the rat race is that even if you win, you’re still a rat.’

In that spirit, I enjoyed reading the reminder in this picture. The quote is from Ichiro Suzuki, a baseball player (currently for the Seattle Mariners) and clearly a success in his field. I found Ichiro’s words printed on a Starbucks coffee cup, and fancied them even more than the maple latte inside. I hope you enjoy them too.

P.S.: Yes, I do more reading than just Starbucks cups.

Sir Arthur on TV

Last week I reread an old classic SF novel, and noticed some remarkable details in this passing comment by one character about the fictional 21st-century Utopia:

"… there are too many distractions and entertainments. Do you realize that every day something like five hundred hours of radio and TV pour out over the various channels? If you went without sleep and did nothing else, you could follow less than a twentieth of the entertainment that’s available at the turn of a switch! No wonder people are becoming passive sponges — absorbing but never creating. Did you know that the average viewing time per person is now three hours a day? Soon people won’t be living their own lives any more. It will be a full-time job keeping up with the various family serials on TV!"

Arthur C. Clarke, Childhood’s End, 1953

Of course, in this passing reference Clarke probably wasn’t trying to make a serious prediction. Nevertheless, Sir Arthur’s astute understanding of the future growth and effects of TV is impressive, all the more so given TV’s primitive state when he wrote that in 1953.

Some perspective. According to Wikipedia and TerraMedia, in 1953 the first commercial TV licenses were granted in the states of Arkansas, Idaho, Kansas, Maine, Mississippi, Montana, Nevada, North Dakota, Oregon, South Carolina, and South Dakota. Canada had only just begun its first regular TV transmissions the year before, and the states of New Hampshire, Vermont, and Wyoming wouldn’t issue their own first licenses until 1954. 1953 also saw the first TV coverage of the Academy Awards, and the launch of TV Guide.

How did Clarke do? With the benefit of hindsight, let’s see:

  • Three hours a day? Right on: A recent global study reported that the average TV viewing time per person worldwide is just over three hours per day. In the United States, it’s four and a half hours per day. The Japanese top the list at five hours per day.
  • 500 hours of content per day? Far more: At 16 hours per day, that would equal a mere 30 radio and TV stations. In 2006 the United States alone exceeded 2,200 TV stations and 13,700 radio stations. [CIA factbook] That’s not counting programming on "channels" like On Demand and YouTube.

As we often say today, "Who knew?" In this case, Sir Arthur did. Last month he turned 89, and his literary output is still going strong. Hats off to the man!