From: Greg Colvin (gcolvin_at_[hidden])
Date: 1999-12-21 12:09:32
Herb Sutter writes:
> This is a very important topic. I have sat back and awaited replies to Dave's
> question because these are precisely the same issues the library working group
> is wrestling with in the case of the standard library. Allow me sketch some
> high-level thoughts I've been having on this topic.
> What are we trying to accomplish? List a few requirements:
> 1. Be able to add, remove, and change existing components and facilities from
> one version of the library to another.
> a) Add: Pretty easy.
> b) Remove: Moderately easy if other components don't depend on the now-absent
> pieces, harder otherwise; as a silly but real example, trying to removing deque
> would require changing stack's default template argument.
I don't see why we should ever remove a component. If we really need
to the tradition is to deprecate it, and then remove it much later,
> c) Change: Easy for simple cases like adding restrictions, since we're not
> taking away anything that existing code might rely on, only adding stronger
> guarantees. But this is the harder case in general, because this item
> encompasses various kinds of changes, such as code changes (default arguments)
> and semantics (behavior).
For the standard we just shouldn't make these kinds of changes,
except to fix defects.
> 2. Beyond requiring a recompile, not break (which includes changing ANY
> semantics/guarantees) any existing code that uses the earlier version(s) of the
> library. Expressed another way, any code that was legal with the earlier
> version(s) is still legal and means the same thing.
> a) Note that it would be acceptable to add purely new restrictions/guarantees
> that don't interact with any other guarantees that existing code might be
> relying on; another silly example would be to add a requirement that a vector's
> storage be contiguous and aligned on 2048-byte boundaries, which clearly won't
> affect programs that never imagined (and hence relied upon) such guarantees.
> b) Unchanged components should still be usable by code written to use the
> earlier version of the library. For example, the following code should work
> whether you passed it a C++98 vector<int> or a C++200x vector<int>:
> void f( vector<int>& );
> How can we accomplish the above? List a few possible approaches:
> A. Just change it; e.g., in C++200x, say std::stack simply no longer existed.
> This makes #1(a)(b)(c) trivial, but doesn't meet #2(a) because a conforming
> C++200x implementation would be allowed to reject existing
> well-formed-under-C++98 programs that use std::stack.
> B. Add a new namespace; e.g., in C++200x the std namespace means exactly what it
> means in C++98, but there's a new std200x namespace that has the fully new
> version of the library. This likewise makes #1(a)(b)(c) trivial since we can do
> whatever we feel like in the new namespace.
Nope. New stuff goes in std. Old stuff has the same semantics. No
> Issue the first: Would this require duplicating object code for unchanged
> components (i.e., double object sizes)? No; simply have a shared implementation
> (which might not even be templated) and write forwarding functions. This is
> usually a good idea when implementing templates anyway, for example for the
> container<void*> technique.
> Issue the second: Say vector<int> didn't change in any way. One problem,
> pointed out to me by Andy Koenig, is that std::vector<int> is not the same type
> as std200x::vector<int> and the code in #2(b) will not work when passed a
That's one reason that a new namespace is a bad idea.
> Apart from #2(b), I admit I find idea B seductive. Absent a magical new
> feature like namespace inheritance, it is not clear to me how to do achieve goal
> #2(b), but maybe that goal isn't important in itself. Does the solution get any
> better if we use a "white lie" and inherit std200x::vector<T> from
> std::vector<T>, in order to make #2(b) compile when passed a
> std200x::vector<int>? I haven't thought about this at all, but it seems it
> should blow up somehow. You'd probably have to duplicate some or all of the free
> operators, anyway.
> This is meant to encourage discussion, not exhaustively list options. If BOOST
> is indeed active in part to establish existing practice, this is an important
> area where existing practice would be useful in the very short term, i.e., the
> next few months before the Tokyo meeting in April by which time some other
> people and I are hoping to have a tentative answer for this in the form of an
> initial draft of a paper we can work to refine while we're together.
As others have pointed out, Boost needn't be near so stable as the
standard, so we need to work out our own approach. If we are really
going to start versioning then it may be time to set up a CVS server.
The standard library is different. It needs to be the rock solid
foundation for everyone else's code, and simply cannot be changed in
any incompatible way without great wailing and gnashing of teeth. No
amount of namespace trickery can obscure that fact. That's why it
takes years to write a good standard.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk