Article View: comp.std.c++
Article #3986Re: sample auto_ptr template
From: Greg Colvin
Date: Thu, 11 Apr 1996 08:05
Date: Thu, 11 Apr 1996 08:05
126 lines
6851 bytes
6851 bytes
In article <009A0A5CE1159CC0.49802F14@ittpub.nl> "Wil Evers" <wil@ittpub.nl>
writes:
>In article <gregorDpFBCt.A5@netcom.com> gregor@netcom.com (Greg
>Colvin) writes:
>
>> Please remember that auto_ptr is designed to make sure that pointers
>> are deleted when exceptions are thrown, not to be sure that already
>> deleted pointers are not misused. The semantics of auto_ptr are
>> intentionally "as close as possible" to ordinary pointers: if you
>> use a pointer that is already deleted the behaviour is undefined,
>> and the same for auto_ptr; if you use a pointer that is owned by
>> another object (i.e. will be deleted by that objects destructor) the
>> behaviour is well defined as long as the pointer remains valid, and
>> the same for auto_ptr; you cannot tell at runtime whether a pointer
>> is valid, and the same for auto_ptr.
>
>My original question was "Did the committee explicitly decide to allow
>dereferencing of non-owning auto_ptrs? If so, what is the rationale
>behind this?" It seems to me Greg's answer is "Yes, because that's
>what ordinary pointers do." I cannot understand this. Why allow a
>dangerous operation just because ordinary pointers do not prohibit it?
>
>Please note:
>
>1. The previous (April '95 DWP) incarnation of auto_ptr did not forbid
>to have a second, non-owning, pointer to the owned object. However,
>in order to get one, we had to explicitly call the get() member
>function, which returns an ordinary pointer. In my opinion, requiring
>the user to go through all this trouble was a reasonable safeguard
>against accessing released memory and unintended aliasing. In the new
>incarnation, there are no such guarantees: an auto_ptr silently
>changes into a zombie pointer as a side effect of a copy operation.
>
Pre April, an auto_ptr silently changed into a null pointer after
copying, except that trying to copy it was ill-formed. Post April
copying is allowed. Derereferencing a null pointer gives undefined
behavior, as does dereferencing a pointer to a deleted object, so I
don't see such a big difference. Given
void f(auto_ptr<T>);
auto_ptr<T> p(px);
then before April we had
f(p); // unintentionally ill-formed
p->whatever(); // undefined behavior
and after April we have
f(p); // well-formed
p->whatever(); // possibly undefined behavior
It is not hard to create a version of auto_ptr that throws an exception
if the "zombie pointer" is dereferenced, at some cost in performance,
and I hope vendors will provide such versions for debugging at least.
If an implementation provides a garbage collector (which is hard) then
providing a safer auto_ptr becomes fairly easy and cheap. Vendors are
always allowed to define undefined behavior to something more useful.
>2. We all have to pay the price for the committee's decision. The
>new implementation is about twice as complicated - up to the point
>where almost no existing compiler can handle it - and half as
>efficient. Furthermore, dropping a guarantee always breaks existing
>code.
Actually, no compiler has ever been able to compile any version of
auto_ptr, since they all have used member templates.
My implementation of auto_ptr is not, IMHO, significantly more
complicated that before (one more member and a few tests, no big
deal). The complication has always been in the member templates.
>
>What I definitely do not understand is why the new auto_ptr template
>doesn't even allow us to query if it is actually owning the object
>pointed to.
>
This was a hard call, and I'm open to suggestions. Adding a mutable
member to a class is never pretty, but making the member visible in any
way is ugly: I don't like for a const argument to change its value,
and I think of the value of an object as being whatever its public
interface reveals. Thus, I find "mutable bool owner" just barely
tolerable, and "bool is_owner() { return owner;} " quite distasteful.
As a practical matter, I can imagine implementations of auto_ptr that
do not store the ownership in the auto_ptr, but perhaps in the bowels
of an OS provided garbage collection system, such that is_owner() might
be very hard to implement efficiently.
Also, I found it very hard to contrive examples where is_owner() would
actually be useful. I think most such examples would involve passing a
reference to an auto_ptr to a function that may or may not then take
ownership. In that case, the callee can always zero out the auto_ptr
argument itself. An alternative idiom is:
template<typename T> auto_ptr<T> source_sink(auto_ptr<T>);
...
p = source_sink(p);
if (&*p)
...
>> What you can do is design your code so that you know who owns each
>> object when. The auto_ptr template can help you implement such
>> designs safely. If you cannot design your code to work with
>> auto_ptr you probably need garbage collection of some form.
>
>auto_ptr may have been designed to provide only limited functionality,
>but since it is the only heap object management facility in the
>standard, it will be used in many different contexts. Therefore, I
>think it is quite resonable to ask how easy it is to abuse it. What I
>dislike about the new auto_ptr incarnation is that it is even easier
>to abuse
I still think that being able to tell who owns an auto_ptr will lead even
more "abuse", since if need to ask you will inevitably forget to ask, and
crash as a result. And if you need to know, then your design is probably
not appropriate for an auto_ptr<> anyway. Don't ask, don't tell.
If anyone can think of examples where an is_owner() is really required
please let me know. A workable fudge might be a protected is_owner(),
so that you have to work at abusing it.
Greg Colvin
gregor@netcom.com
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Technical Details
Message-ID:
<gregorDpoGM2.Hw2@netcom.com>Path:
arc1-ca.pugleaf.net!in2.uu.net!bounce-backReferences:
<009A0A5CE1159CC0.49802F14@ittpub.nl>Show Full Headers
Complete Article Headers
From: gregor@netcom.com (Greg Colvin) Message-ID: <gregorDpoGM2.Hw2@netcom.com> X-Original-Date: Thu, 11 Apr 1996 03:06:02 GMT Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back Date: 11 Apr 96 08:05:39 GMT Approved: fjh@cs.mu.oz.au Newsgroups: comp.std.c++ Subject: Re: sample auto_ptr template Organization: Netcom Online Communications Services (408-241-9760 login: guest) References: <009A0A5CE1159CC0.49802F14@ittpub.nl> X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBMWy90+EDnX0m9pzZAQEbagGAmUmhXMA9JJF1Q0F0Kumm8Hze34KKX6VW QrBDR5VwCUJbZ5Rg3Uj29BdLPAKoC2hk =3wCG