Trip Report: November 2010 C++ Standards Meeting

The fall 2010 ISO C++ meeting was held on November 8-13 in Batavia, IL, USA. The post-meeting mailing is now live, including meeting minutes and other information.

I attended this meeting virtually, as I was still recovering from some shoulder surgery. Fermilab’s teleconference facilities are excellent — I think it’s safe to say they’re the best I’ve ever used, and it was very helpful for several of us telecommuters to participate actively in the key design discussions below.

Where are we in the process?

For this and the next meeting (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.

Things are going well and we are on track to complete the Final Draft International Standard (FDIS) for the 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. If it turns out we need another meeting to be able to handle the last of the comment tail, the fallback will be to target FDIS at the following meeting (Indiana in August).

For about five years now we’ve been having three six-day meetings a year, besides smaller unofficial subgroup meetings in person or by teleconference in between official meetings. Because things are going well, we also decided to scale back to two five-day meetings a year starting in 2011, which is what we had after C++98 shipped until work on C++0x began in earnest.

Key design decisions at this meeting

Note: For the first item, I’ll repeat much of the text from the August meeting trip report to make this a standalone post.

Attributes: alignment, noreturn, and virtual control. As reported in the previous trip report, my personal hot button for these past two meetings was that C++0x syntax for override control in particular not look like the following example:

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

The committee has now decided replace these attributes with keywords. The two main options for keywords were:

  • 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).

It was decided to follow the latter — contextual keywords pretty much as used in C++/CLI, down to renaming [[hiding]] as new. Here’s the paper with the wording changes, and here’s how the above example now looks:

class Derived explicit : public Base {
public:
  virtual void f () override;
  virtual double g( int ) final;
  virtual void h() new;
};

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. The committee confirmed the decision reported as tentative in the previous trip report, namely to change [[align]] to a keyword and leave [[noreturn]] alone.

With these changes, the only two standard attributes are [[noreturn]] and [[carries_dependency]].

noexcept, part 1: Destructor and delete operators noexcept by default. This tentative resolution from Rapperswil was mostly adopted. Briefly, every destructor will be noexcept by default unless a member or base destructor is noexcept(false); you can of course still explicitly override the default and write noexcept(false) on any destructor. This means that the vast majority of classes should be noexcept. The papers containing the exact wording changes are here (destructors) and here (delete operators). For detailed rationale and ranting about why this is a Good Thing, see the previous trip report.

noexcept, part 2: noexcept now partly applied to the standard library. We also passed the first set of papers to apply noexcept to the standard library, including changing functions marked throw() or specified “Throws: Nothing” to be marked noexcept, and removing non-empty exception specifications from the standard library.

Restricting implicit move generation. A hot topic going into this meeting was that move operations could be generated implicitly for an existing type in ways that would be surprising and incorrect (i.e., break the invariants that should hold on all objects of that type). The previous rule was to generate a move constructor and move assignment operator implicitly if the class had no user-declared copy constructor and the move constructor would not be implicitly defined as deleted. Several options were discussed at length, including not generating move implicitly at all. In the end, the decision was that implicit move was both desirable but needed to be generated less aggressively to ensure correctness, and so now the rule is to generate a move constructor and move assignment operator implicitly if the class had no user-declared copy constructor and the move constructor would not be implicitly defined as deleted (same as before) and the class has no user-declared copy or move assignment operator or user-declared destructor. Here’s the paper with the wording changes.

Looking forward

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

  • March 21-26, 2011: Madrid, Spain
  • August 15-19, 2011: Bloomington, IN, USA

Herb

18 thoughts on “Trip Report: November 2010 C++ Standards Meeting

  1. Yes, I know about pure virtual, but that makes the base class abstract. I want something which doesn’t make the base class abstract, but still forces derived classes to implement a virtual function.

    class B explicit {
    virtual B* clone() must_override {
    return new B(*this);
    }
    };

    class D : public B {
    virtual B* clone() must_override {
    return new D(*this);
    }
    };

    class F : public D {
    }; // error as the clone function wasn’t defined.

  2. Just a couple quick small things:

    I’ve been browsing through N3225, and it looks like the automatic move constructor and assignment method won’t be generated for std::exception or derivatives (thanks to the new restrictions); is this intentional? I also see that 15.3.16 still specifies that caught objects are copy-initialized from the thrown object; I’d have thought this would be a great place for a move operation (particularly in low-memory situations, although admittedly exceptions tend to be pretty small).

    Also, I noticed a typo on p. 645 in the header synopsis:

    template struct hash;

  3. We already have pure virtual for that. (Nothing says you can’t provide an implementation; see 10.3.11.)

    Or did you want something that doesn’t also make the class abstract?

  4. I’m also guessing a very low probability for a `must_override` keyword? For virtual member functions which has implementation in base class, but must be overridden in derived classes, such as clone-functions.

  5. Wow. This is crazy. Am I the only one who doesn’t like these virtual control attributes/keywords to begin with? Can someone convince me (or link to an article convincing me) why these are good? It seems to me that they make the language more complicated for very little benefit. It’s not usually that hard to debug code that accidentally hides or overrides a base-class function.

    I can understand putting in attributes as compiler checks. For example, the standard could recommend that compilers generate warning any time you hide or override a base-class function. Then you can add attributes to the derived class functions to clarify your intentions kill the warnings. Or perhaps, you could only have a warning for when a function not declared as virtual overrides a virtual function or when the base-class function has a [[final]] attribute.

    @Herb Sutter – I completely agree with you that attributes should have no semantic effect on a program, but why was the answer to turn them into keywords? Why wasn’t the answer simply to remove their semantic effect?

    Speaking of which, I’m getting tired of keywords that have multiple meanings. ‘auto’ is bad enough, but it’s somewhat acceptible because it’s hardly ever used for its original meaning. But now we have ‘new’, ‘delete’, and ‘explicit’ meaning completely different things from what we’re used to. I can understand the reasoning behind this if people are dead-set against context-sensitive keywords and they’re also dead-set against introducing new global keywords. But if we’re going to have context-sensitve keywords anyway, why not make them something unique and descriptive to add clarity?

    @Dalle – To your first question: I hope not. I hope these keywords have no effect on classes derived from base classes that use them. Then again, I’m kinda hoping they have no effect at all (except, perhaps, to disable warnings).

    Similarly is it *REALLY* necessary for destructors to be noexcept by default? I agree that all destructors should be noexcept, but should we make the language harder to use in order to achieve this goal? By making it the default, we’re making it so programmers have to learn that certain special functions (destructors) that behave differently when “noexcept” isn’t specified. Why not try to keep the language more consistent and therefore simpler? Why not issue a warning if a destructor isn’t marked “noexcept,” then if folks want to clean up their warnings, they’ll have to add it themselves.

    I can think of a lot of useful warnings to add that would catch plenty of errors and be easy to turn off using attributes. For example, if a single-argument constructor isn’t declared explicit, you could generate a warning unless the [[implicit]] attribute is used. That’s just off the top of my head.

    p.s. Why is [[noreturn]] an attribute and noexcept a keyword? Don’t they both express similar things and allow for similar compiler optimizations? IMO, they should both be attributes. In either case, if the code is well-formed, they have no semantic effect.

  6. We plan to work on TR2 (the second set of standard library extensions) right away as soon as C++0x is done. TR2 has one thing voted into it so far: file system iterators. Other likely candidates for inclusion in TR2 are reader-writer locks, thread pools, sockets, and other features.

    As for concepts and modules, it depends entirely whether the people who originally proposed those features, or other experts, decide to return to work on them further to progress the proposals. In my own opinion, what each of these two features needs most at this point is some real-world experience to work through its design, to find and fix the design bugs and prove that the approach is solid.

  7. @Herb: Everybody appreciates all the hard work you guys have been putting into C++0x, and a break is well deserved, but I guess the worry we all have is that when you use phrases like “what we had after C++98 shipped” it implies that the committee is going to go into hibernation again, doing little more than defect reports.

    We’re all looking forward to concepts, modules, and TR2, and it would be a shame to have to wait 13 years for them. When does the committee expect to have these TRs ready?

  8. @Alfonse: There are several reasons. Briefly:

    1. Like we did after shipping C++98, we need to stop changing the language for a time to let implementations catch up. No compiler implements 100% of draft C++0x yet (though I should add that many do implement major features, and as usual EDG is out in front leading the way to 100% conformance).

    2. The committee is about exhausted. Besides three weeks a year of international travel (and the meetings are each six days, including Saturday, where most days are dawn-to-late-night work for most people), there’s a lot of time spent between meetings preparing for them, working on designs, and not to mention having additional meetings by teleconference (typically 4-6/year lately) or in person (typically 1-2/year extra face-to-face meetings lately for large subgroups).

    @jalf: We decided at our August 2010 meeting to scale back to two meetings a year. That was only done once we saw the volume on the final round of international comments and had triaged them all and resolved something like half, including all the controversial ones, and knew we could make the current schedule with high confidence. Even so, I’m scheduling the second meeting of 2011 for August in case we need another one after Madrid to finish the FDIS, but we probably won’t need it.

    @Keith: “alignas” now joins “alignof” as a full reserved keyword (not a contextual keyword).

  9. If a base class has an class-virt-specifier (explicit, that is), is this property applied to derived classes as well?

    For instance, is the following well-formed or ill-formed? I would expect this would be ill-formed.

    class B explicit {
    virtual void h();
    };

    class D : public B {
    virtual void h();
    };

    By the way, is it possible to derive from unnamed classes using decltype?

    For instance, is the following well-formed or ill-formed?

    class {
    virtual void h();
    } b;

    class D : public decltype(b) {
    virtual void h();
    };

  10. @Alfonse: I’d imagine it’s because the committee members have lives (and day jobs) they need to attend to. They’re not getting paid for sitting in the committee, so it’s natural to want to keep it at a pace that doesn’t place too many demands on the committee members.

    But that said, it does seem surprising to scale down effective immediately. I’d have expected 3 meetings in 2011 as well, just to make sure C++0x gets out the door without further delays.

  11. Hi Herb,

    Thanks for the report; I always appreciate these.

    Is “align” a contextual keyword, or a fully reserved keyword?

  12. This is all well and good, except for one thing. Why scale back the meetings?

    It seems to me that C++0x advanced much faster during the 3 meetings-per-year period. There are a number of parts of C++0x that were important but were put off in the interest of getting C++0x out the door. Concepts, Modules, etc.

    I thought the committee was going to move to a 3-5 year release schedule. If so, then the committee needs to be more proactive in getting specs out the door. And the 3 meetings seemed to make that happen more effectively.

  13. Hi Herb,

    In the main text you write:

    “the fallback will be to target FDIS at the following meeting (Indiana in August).”

    while at the bottom you say:

    “August 15-19, 2011: Bloomington, IL, USA”

    There’s a Bloomington in both Illinois and Indiana, but you have to pick one. :-)

    Cheers,
    Alex

Comments are closed.