Although I had to spend a substantial part of my time in Santa Cruz preparing to teach a generic programming class, I do have a little to say about what happened.
Leadership Vacuum?
The week started off rough, with an announcement from Bill (P.J.) Plaugher that, at the end of the meeting, he would resign his post as our Convener. I don’t understand all of the Convener’s duties, but among other things s/he is responsible for shepherding the committee towards a completed standard, negotiating deadlines with ISO, and more importantly, re-negotiating if the committee is going to miss a deadline. I believe we’ve already missed one deadline for C++0x, and now we might easy miss another.
Not having Bill in that role is going to be a great loss to the community, since he has over 30 years’ experience with various ISO standards committees, so he knows how to deal with all the procedural issues that arise leading up to a release.
Bill is also one of the few people who prominently holds open the space of conservatism and discipline on the committee: it’s all too easy to get excited about “nice ideas” that—if we’re going to ship C++0x—we can’t afford to entertain. I have counted on Bill to point out those moments, and while I don’t always agree with his perception, I take his strong opinions very seriously. I hope he’ll keep it up even though he has no official duty to do so.
As far as I know, nobody has volunteered yet to take over his position, so if you really want to get involved with the committee and make a difference, this is a great opportunity. Hint, hint.
Progress on Move Constructor Exception Safety
Rani Sharoni and I wrote a late paper proposing a whole new approach to the throwing move constructors issue. It’s actually Rani’s brilliant insight from start to finish. The only thing I deserve credit for here is listening to him long enough to realize he had the right answer (even though it sounded crazy to me at first), and for bringing it to the committee meeting.
Anyway, it was a long shot, but I think Bjarne looked favorably on the
proposal, so it was the first thing presented during his Evolution
Working Group’s one day of work.1 The EWG was suitably impressed with
the proposal, but I was even more impressed with the EWG: it’s rare that
a proposal goes before the committee and is only improved without
sustaining damage, but that’s what happened. Among other things, the
noexcept keyword from the proposal Doug and I originally
wrote
to address the issue was revived, to be used both in lieu of
throw(false) and to act as the operator that can detect some
nonthrowing operations.2
Once EWG had moved the paper forward, Doug Gregor—in typical “Doug style,” without even being asked—jumped right in and began the hard work of drafting new standard language to accomodate the EWG changes.3 He applied an enormous amount of elbow grease, and by the time the meeting was over almost all the core language had been re-written. Thanks, Doug! Then he carried the proposal into the Core Working Group for evaluation, and I did the same in Library.
Apparently the paper did very well in Core, with only some corrections
in technical wording and syntax suggestions (they like noexcept as
opposed to noexcept() as the terse form—I happen to disagree).
Getting Core’s blessing is a huge step towards
standardization—especially at such a late date in the
process—because it shows the proposal is baked enough to be considered
by real C++ compiler writers to tractably implementable in real C++
compilers.
I wasn’t as immediately lucky in the Library Working Group. Although there was a very positive reaction from many in the room—including Bjarne and Howard Hinnant, the chair of LWG—somehow, a few people decided that the proposal would make it difficult and perilous for users to write correct move constructors. In fact it is exactly the opposite.4 By the end of a private conversation, later those people may not have fully understood the issue but they were willing entertain the idea that they had gotten it backwards. There was also a protest against the amount of “invention” (as opposed to “standardizing existing practice”) being done at this late stage of the process—a legitimate concern. Eventually it was decided to postpone further consideration of the proposal in LWG “without prejudice,” to give us more time to evaluate the idea. Fortunately, after that session, the protester against invention confided in me that he might have been too hasty and by the time we consider the paper at the next meeting, he’ll probably be inclined to vote for it.
So, in all, Santa Cruz was very kind to Rani’s idea, and left it very much alive and, in my opinion, even improved on the original proposal. It’s almost a miracle that a late proposal asking for new core language features did so well, and it looks very much like we’ll be standardizing it at the next meeting in…where is now?…ah, yes: Pittsburgh, Mar 8-13.
Oh, yeah: and since the proposal stands the world as we knew it on its head, we’ll need an update to the article where the discussion started.
-
The EWG is quite appropriately winding down its activity as we try to stabilize the current Working Draft for release as C++0x. ↩
-
Bjarne made a big point of saying that the tradition that a committee member should be prepared to “give up a kidney for each new keyword he introduces” might have been doing more harm than good, so I stopped worrying quite as much about the health consequences of adding
noexcept.
↩ -
Follow this link to see what changed, or simply read the final proposal. ↩
-
Rani’s idea is actually makes the world a lot safer: if N2983 is accepted, it will be perfectly OK to write a throwing move constructor. One less thing for class authors to worry about. ↩

Hi Dave,
Thanks for the kind words and the interesting meeting notes.
I’m honored to even potentially contribute to your novel work. Seems like there is great distance between idea/intention and standard level formulation.
I most credit you for challenging my original proposal to relax the strong guarantee altogether (LWG DR #985). I then tried to figure how to allow throwing move (favoring usability) without over-complicating the current specification in a way that seems hard to follow (e.g. adding conditional strong guarantee and specialization for pair[string, legacy-type]).
Though not in the same magnitude, allowing throwing move reminds me of allowing throwing copy that, AFAICT, was forbidden until late stage of C++98 standardization. It also favor usability while not over-restricting the (library) implementation. I wonder if you got push-back when you proposed “allowing throwing copy” back then…
Thanks, Rani
(Quote)Dave, do you feel like there is a larger volume of work going on for this standardization than with the ‘98 one? I only have the anecdotal evidence of the ISO postings, but it sure seems like the volume of proposals and the amount of work is pretty high in comparison.
(Quote)I don’t really have a good perspective on it, since I came into the first standardization process way too late to see how much work went on. However, if I compare the 1208 pages of the current WD, which includes all the old text
(Quote)like thiswhere changes have been made with the 748 pages of the ’98 standard, I’d say we’re not even close.Well, it’s not an easy question to answer and the picture for the core language and the library are different.
The original standard wasn’t all done within the WG21 ISO process, especially with the core language part: It came in as a base document (the non-annotation parts of the ARM), and some bits also came from the nearly finished C standard I believe (e.g., the preprocessor). So if one uses “page count” as a rough approximation, I don’t think we can compare the 300pp->400pp growth in C++0x core language specs against “300pp” in the original: Most likely the original standardization process added much less than 300pp to the base documents.
Similarly, looking and postings and proposal volumes isn’t a good comparison either. Much of the first standard was developed with relatively minor networking support: Many carried around multi-kilogram postings in paper form, not everyone at the meetings had a laptop even in 1995 (passing around a floppy was the high-tech alternative), and “distribution” during committee meetings meant dropping off a pile of copies on a designated table in a conference room. All-in-all, I think that much of the “hashing out” process that is now relatively transparent via the reflectors and multiple paper revisions had an similar-but-opaque counterpart in offices worldwide.
That said, my sense is that wrt. the core language, the two efforts produced comparable amounts of features, but the first effort was more “revolutionary” in its work by developing the specs for templates and exception handling in particular (the base document mostly just had a sketch for these things). On the flip side, I think the C++0x additions have noticeably better wording (and hopefully that will help get implementations to better match each other).
I cannot say much about the library, but I’m pretty sure that nothing matches the “revolutionary” aspect of integrating the STL in the WP of round 1.
(Quote)Thanks Dave, you caught the essence of what I wanted to say. I am pretty sure that everybody is going to do an excellent job, without a lot of friction getting generated in the end for this or that. I wish you and the committee the best; I know that despite the difficulties of getting all the resources involved (human, non – human and inhuman) to play through nicely, things will get done.
As for a lot of the cut features, I have a feeling that they will be emerging in boost in one form or the other (if they are not already in anyway in some form); the ordeal for the new standard did bring a lot of interesting material.
Best Wishes,
A concerned developer.
(Quote)N2983: “In other words, it [nothrow_move_constructible] returns true only when it can prove the move constructor doesn’t throw, and is allowed to return false even when the move constructor can throw.”
That should probalby be “…even when the move constructor doesn’t throw.” — Double negative confusion.
So, is noexcept part of the function type or not? What about function pointers? What about template argument deduction?
template<bool NE> void foo( void(*pf)() noexcept(NE) ) {}(Quote)Yikes! Great catch; I’ll make that fix right away.
Well, you can read through the proposed core language changes to be sure, but since it sits in the grammar right where exception-specifications are today, I expect the rules are the same for
(Quote)noexcept.Hi! Thanks for this report! I’m just checking out the new paper. Though, it seems, the vector::reserve function suffers from the same bug as the one version you still have in your article series: The second for-loop in the catch(…) clause should be for(;i–>0;) instead of for(;i>0;–i). The index is off by one.
(Quote)Thanks, we’ll make sure to fix it.
(Quote)Excellent news that this has progressed so far.
I’m curious about this part of N2983:
I see three possibilities for new code (for example, defining something new along the lines of
vector::resize):move_if_noexceptto provide the strong guarantee.I’m undecided between the first two, but the last seems to me to complicate our whole approach to exception safety. Would you agree that it’s quite a big deal to add conditional strong to our current simple set of basic, strong and nothrow exception safety concepts?
(Quote)The thing is, we’re not adding anything new. The standard is already chock full of conditional guarantees like that one. For example, §23.2.4.3 [lib.vector.modifiers] says of the
insertfunction,Option 1 above is a premature pessimization, sort of like indiscriminate object-level locking for concurrency: there’s no reason to think the client needs the strong guarantee at this level of granularity. Option 2 is less evil, but it will in some cases force clients to needlessly pessimize their code, e.g. by using copy-and-swap to get the strong guarantee when the algorithm actually provides (but does not promise) it.
(Quote)I am personally quite frustrated by this situation, where for a million reasons and non – reasons the C++0x (C++1x actually, let’s not be optimistic any more) standard gets delayed again and again. What it does is create a bad picture for the language itself since a lot of people are holding back before writing C++0x specific code in real world applications. This creates two issues: C++0x use gets marginalized to the semi – complete implementation of std::tr1 some compilers implement to a certain extent (or all of it). C++0x – only features like lambdas etc have an excuse for not being available because it is part of the next standard anyway. Everything is waiting for the NEXT standard which is right now prey of an Osborne Effect.
I think that the workarounds and buildups that boost does on C++0x semi – compliant compilers are quite noteworthy, but because C++0x is still a work in progress (and not an almost final draft) in a lot of sections the will to experiment for the “best” implementation will simply set back the one that is good enough. There is no effort that leads to certain failure than the attempt of keeping everybody happy.
Quite frankly, I am tired of all the musical chairs. Please, just complete the standard before trying to make it smarter and nobody will say: “oh, you missed a spot” because you have already covered all others; it is already hurting a language we all have a lot of uses for in dramatic ways.
(Quote)SomeCppGuy,
Thanks for the feedback. Unfortunately, you’re sorta preaching to the choir over here. The only new things I want to add at this point are fixes for things we broke by adding other features (for example, adding rvalue references broke the exception-safety guarantees of
(Quote)vector::push_back, and we really can’t fix that problem without cripplingvectorw.r.t. move semantics or adding a new language feature likenoexcept). That means I have to be circumspect about some really good ideas that would make everything better for everybody, like generating default implementations of move constructors akin to our default copy constructors as proposed by N2953. I like that one so much that I couldn’t bring myself to actually vote against it; In that one case I voted “neutral” instead. In general, though, I think the committee did an admirable job of killing off or postponing non-essential features in Santa Cruz; a lot of things that might otherwise be worth pursuing were stopped (e.g. SCARY iterators, therangetemplate, and unified function syntax). Now if we could just get people to hold these proposals until after C++0x ships so we could stop spending committee time on them…While I would like to see the new standard be released as much as everyone else, I would prefer to have fewer features that are well thought-out and “smart” rather than a lot of features that are stuffed in for the sake of having something there. While it’s very hard to get something perfect, C++ already has enough of the cram-it-in-last-minute ideas from ‘98. I’d rather not see it go the route of Java with its half-dozen I/O libraries.
(Quote)