The Casting Vote

by Sean A. Corfield

At this point in the process, you should not be expecting large changes. In fact, France took the position some time ago that there should be no more extensions and the UK also wants to see stability. So now we are attempting to make only small changes. Sometimes those small changes can be very illuminating, especially when the committee have to adopt a change that makes the draft more compatible with existing practise rather than the other way around.

Stabilisation

At the Santa Cruz meeting we were supposed to be ready to ship out the second Committee Draft, triggering a second ANSI Public Review. However, discussions within WG21 on Sunday evening made it clear that too many small changes were planned for this meeting and we would have no choice but to slip the schedule by one meeting. Most committee members are now confident that we can achieve an appropriate level of stability by Stockholm (July '96) to be able to move on to the next ballot. It's possible that we might make this up later as the improvements in the draft should help it go through subsequent ballots more smoothly.

Despite the noticeable slowing of change, a remarkable number of issues were dealt with this time around.

Conversions

Two conversion-related issues were cleared up, one of which brings the draft in line with existing practice:

struct A {
	operator int();
	int	a;
};
struct B : A {
	operator long();
	int	b;
};
B b;
int i = b;

The draft used to say that B::operator long() would be called here but most compilers throw all the conversion operators into the pot and pick the best match, A::operator int(). The committee agreed this was more intuitive and decided to make the majority of compilers a little more conforming!

The other conversion issue concerns "slicing" where a derived class object is assigned or passed to a base class variable by value. This is often not what was intended and can lead to subtle bugs.

A a = b;	// from above
// b.b is silently thrown away

The committee decided to remove this conversion since it does not fit in with the other "polymorphic" conversions and code can easily be fixed by using references to the base class instead.

Author's note, 23 June, 1999: this is very confusing! In fact what the committee removed was the specific paragraph that mentioned slicing conversions which was a hangover from the ARM. Slicing conversions are still allowed because, of course, the derived object will bind to the argument of the base class copy constructor (if such a constructor is present). My thanks to 'stevieo4 at erols.com' for bringing this to my attention!

Template cleanups

A common question asked regarding templates is "when are they instantiated?". The draft doesn't say. Conceptually, instantiation occurs some time between actual compilation of a file and link time. For some compilers, that actually means during compilation. Why is this important? It gives guidance to implementors, library vendors and users about how they should be expected to deal with compilation and linking of template code and what should be expected of libraries. A proposal by myself and Dag Brück of Sweden, accepted in Santa Cruz, replaces the basic eight translation phases, inherited from C, with nine - the extra phase being instantiation between translation (phase 7) and linking (originally phase 8). The exact wording may change as a result of other template resolutions but the draft is now quite clear that libraries can be built from code that uses templates and that instantiation is a pre-link-time activity that may require template source code to be available. Of course, implementations behave "as-is" so they may roll instantiation into either compilation or linking depending on how the implementation is constructed.

Another comment that is heard regularly amongst those who've read the draft is "what on Earth does clause 14 [templates] actually mean?". Partly from its ARM heritage and the result of many, many changes being applied since, the clause describing templates had become very difficult to follow and was imprecise at best. I have been trying to find time to rewrite the clause for over six months so my hearty thanks to Josée Lajoie, the X3J16 vice chair, who has done a tremendous job of reorganising the clause and clarifying the wording. The committee voted unanimously to adopt her rewrite and several committee members have reviewed it and made comments, most of which have been integrated already. I shall be integrating the remaining comments and completing the cleanup over the next couple of weeks.

Controversy<>

A much-debated issue finally came before the full committee. Since the days of the ARM, the intent has always been that template definitions were somehow "found" when needed for instantiation. The first C++ compiler, Cfront, worked this way as have some other compilers since. There are difficulties with this approach, however, and many compiler vendors, especially on PCs, decided to require that template definitions were available at compile-time by forcing users to include the entire definition and all supporting machinery in header files. Instantiation is then performed during, or immediately after, compilation.

Eventually, in November '94, the committee agreed to sanction this extension and made some minor changes to the draft to allow multiple copies of template bodies to appear in multiple translation units, breaking with the traditional interface / implementation separation granted for normal functions.

However, the pro-"inclusion" faction within the committee continued to lobby - they wanted the "separation" facility removed so they would not have to support it. The battle has been generally waged with hot air and Fear, Uncertainty and Doubt. In Santa Cruz, several hundred man-hours were devoted to rehashing old ground and hearing the same tired arguments over and over again. No new technical information was presented. Separation was "slow" and "hard to implement". Inclusion "leaked names" and "went against sound engineering principles". The pro-inclusion group put forward a proposal to remove support for separation, thus breaking Cfront-developed template code, and it was clear this would get a majority vote within X3J16. It was not clear that WG21 were in consensus on this and, after much political wrangling, the formal vote was in favour but with adoption deferred to Stockholm to allow further technical work to be done. That technical work can focus on the shortcomings of both models and hopefully generate a clear consensus within the international committee.

Library fashions

Transparent locales are out, bidirectional streams are in!

The locale issue has proved controversial at previous meetings and at least it is now laid to rest. If you don't know what a transparent locale is, the decision is unlikely to affect you.

The lack of bidirectional streams might be more surprising. iostream and fstream are so common in implementations that it seems incredible that the standard didn't support them. Now it does, although I noted that no national body had objected to their absence, i.e., their addition does not resolve a specific ballot comment.

Still to come

After all the minor issues dealt with this time (there were around sixty formal motions), the issues lists are shrinking to encouragingly manageable sizes and most issues should be closed out before we ship the second CD.

One of the "big" outstanding issues is name injection which just refuses to die. Every time we think we have got it licked, a new problem with our solution crops up and we go back to the drawing board.

Implementation experience with the combination of templates and namespaces is beginning to throw up some interesting (i.e., hard) problems and member templates are sure to provide similar puzzles to be solved.

The library still needs a lot of work: some of it has never been implemented because it relies on language features that simply aren't supported by compilers yet. As more people focus on the library, more issues come to light and so the issues lists ebb and flow.

Our best guess says Stockholm will see sufficient stability to move on. Further slippage would certainly be bad for C++ and its users.