The Casting Vote I
by Sean A Corfield
CD2
In my last column I said that we were poised on the brink of a critical decision: to ship the second Committee Draft after the Hawaii meeting. We succeeded. That means that a second ANSI public review is about to start and each National Body will study the draft to decide its vote in the forthcoming ballot.
The most important effect of shipping CD2 is stability. In Kona in November the committee made very few changes that were anything but editorial. Our charter for the meeting was to clear all our issues lists and create the CD. The latter was particularly unusual: normally the committee vote to accept a bunch of changes and a small team edit them into the working paper after the meeting and the resulting document is approved at the next meeting. In Kona, we voted on a few changes in the middle of the meeting and used the next day to produce the new working paper. This left us with only two motions on Friday: accepting the freshly printed working paper, and submitting it for CD. The logistics of editing in the changes and actually producing the document at the meeting would make a column of its own - needless to say, Andrew Koenig and his team managed the job very smoothly.
Those final changes
In theory, very few of the changes accepted in Kona are likely to affect the average programmer. We're mostly fixing the dark corners of the language now but there were a few clarifications that have slightly wider impact.
Now you see it...
The language change that I was most concerned about was
access checking the delete
operator. If you've read what the draft standard says about this, you'll
probably agree that it is virtually unimplementable, effectively requiring
runtime checks that would place a high overhead on implementations. The
Core I subgroup considered various ways to clarify this and finally settled
on the following:
- When a destructor is defined, a publicly accessible,
unambiguous
operator delete()must be found (which can include the globaloperator delete()).
What concerns me about this change is that it breaks the idiom
of making a base class operator delete()
private in order to restrict the dynamic memory operations used on a class -
derived class destructors will be ill-formed because the visible operator
delete() is not accessible. I sat in on this discussion:
there did not appear to be a reasonable solution that still respected access
control so I guess we'll have to live with this one.
Can you point to it?
The other change which bothered me - and bothered the UK sufficiently
to vote "no" on submitting CD2 - is a library change. The working
paper is very vague about allocator classes. The intent is that an allocator
encapsulates memory allocation and deallocation for a particular memory model
(e.g., near, far, huge on Intel architectures). The concept of "memory
model" is a broad one and can be taken to encompass shared memory, persistent
memory and so on. The allocators described in the working paper supported this,
in theory, by having member types for pointer
and reference, allowing
managed memory that is accessible via smart pointers.
I say "in theory" because in practice the working
paper was so vague about pointer
and reference that
some people argued that it was unimplementable. This was compounded by
the fact that allocators are intended to be objects and that the working
paper implied that containers must carry around these objects as part
of their internal data structures�some container operations were very
poorly specified in this area.
I, and a few others, argued that the draft was clear enough but you just might not like what it said! In the end, after some heated exchanges and hard bargaining, allocators were crippled but not beyond recovery. What CD2 says of allocators is:
referenceis alwaysT&because C++ does not support smart references,- the standard containers are only guaranteed to work
with allocators whose
pointertype isT*, - the standard containers are only guaranteed to work with allocators whose instances compare equal and are interchangeable.
I have no real problem with the restriction on reference
although it precludes conforming extensions (such things are possible,
if rather exotic). The restriction on pointer
means that you cannot write an allocator for shared memory, for example,
and have it work with the standard template library. The restriction on
instances makes it extremely hard to write efficient allocators that handle
more than one arena of memory.
Despite the claims of unimplementability, I have allocators
that work with shared memory and I have containers that work with those
allocators. Allowing for limitations of current compilers, these allocators
and containers are intended to be standard conforming: the change at Kona
has effectively broken my code. I believe very strongly that the standard
template library should provide better guarantees of operation with user-supplied
allocators. All is not lost, however, since I intend to work with Matt
Austern�one of the authors of the proposal that introduced the restrictions�to
specify requirements on pointer
and, hopefully, instances that will allow the restrictions to be relaxed
during the resolution of CD2 comments.
The next step
Expect to see smaller and smaller columns in this series as the committee move into "minutiae mode". Our next meeting is in Nashua, NH and we will be reviewing comments from the public review and any that have been forwarded from National Bodies. I suspect that most of the public comments will be requests for extensions and they will therefore be rejected�the time for change has passed!