Thread View: comp.std.c++
7 messages
7 total messages
Started by Wil Evers
Wed, 10 Apr 1996 11:22
Re: sample auto_ptr template
Author: Wil Evers
Date: Wed, 10 Apr 1996 11:22
Date: Wed, 10 Apr 1996 11:22
60 lines
3667 bytes
3667 bytes
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. 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. 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. > 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 than the old one. - Wil --- [ 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 ]
Re: sample auto_ptr template
Author: 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 ]
Re: sample auto_ptr template
Author: Greg Colvin
Date: Thu, 11 Apr 1996 14:53
Date: Thu, 11 Apr 1996 14:53
38 lines
2151 bytes
2151 bytes
In article <gregorDpoGM2.Hw2@netcom.com> gregor@netcom.com (Greg Colvin) writes:
>
>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
Silly me. Of course that should be:
... Given
void f(auto_ptr<T>);
auto_ptr<T> g();
auto_ptr<T> p;
then before April we had
p = g(); // unintentionally ill-formed
f(p);
p->whatever(); // undefined behavior
and after April we have
p = g(); // well formed
f(p);
p->whatever(); // possibly undefined behavior
I hope I got it right this time :-)
[ 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 ]
Re: sample auto_ptr template
Author: Igor Boukanov
Date: Thu, 11 Apr 1996 16:47
Date: Thu, 11 Apr 1996 16:47
30 lines
1906 bytes
1906 bytes
Greg Colvin (gregor@netcom.com) wrote: > 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. But why in this case instead of adding mutable member just change auto_ptr<T>(const auto_ptr<T>&) to auto_ptr<T>(auto_ptr<T>&) and auto_ptr<T>& operator=(const auto_ptr<T>&) to auto_ptr<T>& operator=(auto_ptr<T>&) This will explicitly reflect the semantic of auto_ptr and if somebody really want to change the state of const object, they can explicitly wright about this: auto_ptr<someType> autoPtr(const_cast<auto_ptr<someType>&>(autoPtrConst)); -- Regards, Igor Boukanov. igor.boukanov@fi.uib.no http://www.fi.uib.no/~boukanov/ [ 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 ]
Re: sample auto_ptr template
Author: J. Kanze
Date: Fri, 12 Apr 1996 14:57
Date: Fri, 12 Apr 1996 14:57
37 lines
2509 bytes
2509 bytes
In article <4kjcvb$ghf@ugress.uib.no> boukanov@sentef1.fi.uib.no (Igor
Boukanov) writes:
|> Greg Colvin (gregor@netcom.com) wrote:
|> > 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.
|> But why in this case instead of adding mutable member just change
|> auto_ptr<T>(const auto_ptr<T>&) to auto_ptr<T>(auto_ptr<T>&)
|> and
|> auto_ptr<T>& operator=(const auto_ptr<T>&) to
|> auto_ptr<T>& operator=(auto_ptr<T>&)
|> This will explicitly reflect the semantic of auto_ptr and if somebody really
|> want to change the state of const object, they can explicitly wright
|> about this:
|> auto_ptr<someType> autoPtr(const_cast<auto_ptr<someType>&>(autoPtrConst));
We've been through all this before. That was the original version.
Regretfully, makes it impossible to return an auto_ptr from a function.
And one of the more frequent uses of auto_ptr involves returning them
from functions.
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
[ 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 ]
Re: auto_ptr::is_owner()
Author: Nathan Myers ncm
Date: Sat, 13 Apr 1996 23:17
Date: Sat, 13 Apr 1996 23:17
38 lines
2145 bytes
2145 bytes
Greg Colvin wrote:
> In article <009A0A5CE1159CC0.49802F14@ittpub.nl> "Wil Evers" <wil@ittpub.nl>:
> >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.
> I found it very hard to contrive examples where is_owner() would
> actually be useful.
I agree with Greg here: any code that is intended to execute
differently, depending on the value returned by putative member
auto_ptr<>::is_owner(), is just bad code.
I can imagine:
auto_ptr<T> p1;
auto_ptr<T> p2 = new T;
if (...) {
p1 = p2;
}
// what to do here?
The answer is: it's your responsibility to keep track of ownership
of pointers; if you can't do it manually, then automate it with
reference counting or something. That's not what auto_ptr<> is for;
its purpose is to make sure that the value "new T" gets destroyed.
It does that job perfectly; don't ask it to do your job too.
Nathan Myers
ncm@cantrip.org http://www.cantrip.org/
[ 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 ]
Re: sample auto_ptr template
Author: Pulkkinen Esa
Date: Mon, 15 Apr 1996 16:36
Date: Mon, 15 Apr 1996 16:36
41 lines
2545 bytes
2545 bytes
>In article <4kjcvb$ghf@ugress.uib.no> boukanov@sentef1.fi.uib.no (Igor
>Boukanov) writes:
>|> auto_ptr<T>(const auto_ptr<T>&) to auto_ptr<T>(auto_ptr<T>&)
>|> and
>|> auto_ptr<T>& operator=(const auto_ptr<T>&) to
>|> auto_ptr<T>& operator=(auto_ptr<T>&)
IMHO, copy constructors for auto_ptr must be either private or
have non-const parameters.
In article <KANZE.96Apr12130738@gabi.gabi-soft.fr>,
J. Kanze <kanze@gabi-soft.fr> wrote:
>We've been through all this before. That was the original version.
>Regretfully, makes it impossible to return an auto_ptr from a function.
>And one of the more frequent uses of auto_ptr involves returning them
>from functions.
I can't really understand, why it should be possible to return
auto_ptr's from functions - why not define a distinct pointer type
for that purpose - and define conversion from auto_ptr to
that pointer type for returning it from functions. That is -
to return an auto_ptr from functions, you write:
taligent_ptr<T> f()
{ auto_ptr<T> p=new T;
return p;
}
(I have no idea if the 'taligent_ptr' is suitable for this kind of thing,
but its name is as good as any for this example .... )
--
Esa Pulkkinen | C++ programmers do it virtually
E-Mail: esap@cs.tut.fi | everywhere with a class, resulting
WWW : http://www.cs.tut.fi/~esap/ | in multiple inheritance.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads