🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #3986

Re: sample auto_ptr template

#3986
From: Greg Colvin
Date: Thu, 11 Apr 1996 08:05
126 lines
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-back
References: <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