🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

17 total messages Started by veldhuis Tue, 12 Sep 1995 01:41
auto_ptr::reset and auto_ptr::operator=
#1949
Author: veldhuis
Date: Tue, 12 Sep 1995 01:41
52 lines
2037 bytes
:>What follows are my best guesses for the definitions of the operator=
:>and reset functions:
:>
:>  template<class T>
:>  class auto_ptr {
:>  public:
:>    void operator=(auto_ptr<T>& rhs);
:>    T * reset(T *p = 0);
:>    ...
:>  
:>  private:
:>    T *pointee;
:>  };
:>  
:>  template<class T>
:>  inline void auto_ptr<T>::operator=(auto_ptr<T>& rhs)
:>  { if (this != &rhs) reset(rhs.release()); }
:>
:>  template<class T>
:>  inline T* auto_ptr<T>::reset(T *p)
:>  {
:>  	delete pointee;
:>  	return pointee = p;
:>  } 
:>
:>Questions:
Sorry, I have no answers for that. I do have another question/remark.
The way the auto_ptr assignment is setup does have very different semantics 
from all other assignments I know in that the previous value becomes invalid 
after the assignment. Assume :

auto_ptr<int> a, b;

*a = 10;  // Set a to 10.
b = a;    // Set b also to a (10), but deletes a in the process ?
cout << *a;  // crash ??? since a is no longer valid ?


It seems to me that in the assignment a deep copy should be performed in 
stead of a binary copy.

I could be wrong when auto_ptr::release() does only set a flag that its 
pointer still is valid, but it is no longer the owner of the memory pointed 
to. In this case however the implementation of reset would be erroneous since 
that would have to test that flag also. The only correct way of implementing 
this that I can think of would be to use reference counting on the 
pointee. 

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr::reset and auto_ptr::operator=
#1958
Author: Greg Colvin
Date: Wed, 13 Sep 1995 04:51
80 lines
3823 bytes
In article <199509111753.AA15077@xs1.xs4all.nl> veldhuis@xs4all.nl writes:
>:>What follows are my best guesses for the definitions of the operator=
>:>and reset functions:
>:>
>:>  template<class T>
>:>  class auto_ptr {
>:>  public:
>:>    void operator=(auto_ptr<T>& rhs);
>:>    T * reset(T *p = 0);
>:>    ...
>:>  
>:>  private:
>:>    T *pointee;
>:>  };
>:>  
>:>  template<class T>
>:>  inline void auto_ptr<T>::operator=(auto_ptr<T>& rhs)
>:>  { if (this != &rhs) reset(rhs.release()); }
>:>
>:>  template<class T>
>:>  inline T* auto_ptr<T>::reset(T *p)
>:>  {
>:>  	delete pointee;
>:>  	return pointee = p;
>:>  } 
>:>
>:>Questions:

What to do when this==&rhs is still an open issue for the committee. Also,
reset() is supposed to return void, and operator= is supposed to return *this.
(despite what the draft working paper says, which is wrong and will be fixed)

>Sorry, I have no answers for that. I do have another question/remark.
>The way the auto_ptr assignment is setup does have very different semantics 
>from all other assignments I know in that the previous value becomes invalid 
>after the assignment. Assume :
>
>auto_ptr<int> a, b;
>
>*a = 10;  // Set a to 10.
>b = a;    // Set b also to a (10), but deletes a in the process ?

No, the int pointed to by a is not deleted, but is now owned by b, and
*a == 0, that is, a owns nothing.

>cout << *a;  // crash ??? since a is no longer valid ?
>

Yes, *a above has undefined behavior. ,Note that since *0 is undefined
behavior an implementation is free to do anything, including something
helpful like stopping in a debugger or throwing an exception.
>
>It seems to me that in the assignment a deep copy should be performed in 
>stead of a binary copy.

That would require that the type being pointed to have a copy constructor.
If you wish you can write b.reset(new int(*a)) instead of b = a.

>I could be wrong when auto_ptr::release() does only set a flag that its 
>pointer still is valid, but it is no longer the owner of the memory pointed 
>to. In this case however the implementation of reset would be erroneous since 
>that would have to test that flag also. The only correct way of implementing 
>this that I can think of would be to use reference counting on the 
>pointee. 

The whole point of auto_ptr is to enforce a disciple of strict ownership: there
is only one owner of the object pointed to by an auto_ptr, and ownership is
transferred by copying the auto_ptr. Reference counting or garbage collection
would be necessary to provide shared ownership, but the committee carefully
considered and rejected all of my proposals for shared ownership. Strict
ownership is a strict discipline, but it appears to be the simplest and most
efficient semantics that can solve the problem of exception-safe memory
management.

[ Greg Colvin wrote the original auto_ptr proposal, and worked through
  many revisions until it was finally accepted by the C++ committee. -- sdc ]

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr::reset and auto_ptr::operator=
#1962
Author: Scott Howlett
Date: Thu, 14 Sep 1995 02:00
27 lines
1595 bytes
In article <gregorDEtM0t.Hw2@netcom.com>, gregor@netcom.com (Greg Colvin) wrote:

> In article <199509111753.AA15077@xs1.xs4all.nl> veldhuis@xs4all.nl writes:
> >It seems to me that in the assignment a deep copy should be performed in 
> >stead of a binary copy.
> 
> That would require that the type being pointed to have a copy constructor.
> If you wish you can write b.reset(new int(*a)) instead of b = a.
> 

A copy constructor will not suffice in many cases. If a contains an object
of some polymorphic class,you would need to write something akin to
b.reset(a->clone()).

I imagine that this semantic requirement is a sufficient reason for the
_standard_ auto_ptr template not to try to do fancy things like copying its
contents (although it should be easy to derive your own my_auto_ptr template
which does.

-- 
Scott Howlett
Storm Software, Inc.
howlett@netcom.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr::reset and auto_ptr::operator=
#1992
Author: Tony Davis
Date: Mon, 18 Sep 1995 20:16
20 lines
1155 bytes
In article <gregorDEtM0t.Hw2@netcom.com> gregor@netcom.com (Greg Colvin) writes:
> >*a = 10;  // Set a to 10.
> >b = a;    // Set b also to a (10), but deletes a in the process ?
> 
> No, the int pointed to by a is not deleted, but is now owned by b, and
> *a == 0, that is, a owns nothing.

Just to clarify, you are saying that the standard will say that
auto_ptr<T>::reset() does NOlete its pointee, correct?


Tony Davis
ted@cs.brown.edu


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr::reset and auto_ptr::operator=
#2000
Author: Tony Davis
Date: Wed, 20 Sep 1995 23:43
23 lines
1124 bytes
Interesting.

In article <MATT.95Sep18131639@physics2.Berkeley.EDU> ted@cs.brown.edu (Tony Davis) writes:
> Just to clarify, you are saying that the standard will say that
> auto_ptr<T>::reset() does NOlete its pointee, correct?
                            ^^^^^^

That should say 'NOT delete', yes?


> Tony Davis
> ted@cs.brown.edu


Tony Davis
ted@cs.brown.edu


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr::reset and auto_ptr::operator=
#2007
Author: J. Kanze
Date: Fri, 22 Sep 1995 17:13
84 lines
4061 bytes
Greg Colvin (gregor@netcom.com) wrote:

|> What to do when this==&rhs [in operator=] is still an open issue for the committee. 

Does it really need any special consideration.  The semantics of
operator= are defined as:

	reset( other.release() )

There is a sequence point before the call to reset, so other.release
must finish executing before reset is called.

If &other==this, there is still no problem: the pointer is first
released, and so no longer belongs to other/this when reset is called.
The net effect is a no-op.

As this follows from the normal semantics, and is a possible and
reasonable definition of the semantics for this case, why create a
special case.

While in this thread, I'd like to bring up another point which bothers
me.  I'll start by quoting some earlier postings which are relevant:

Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
|> Michael Cook <mcook@cognex.com> writes:

|> >I've been using auto_ptr with g++ (a 2.6 dialect).  G++ generates bogus
|> >warnings for certain expressions, but compiles the code correctly.
|> >
|> >The code it complains about is this:
|> >
|> >    auto_ptr<V> byValue(auto_ptr<V> a);
|> >    a = byValue(b);
|> >    //   warning: initialization of non-const `auto_ptr<V> &' from
|> >    //   rvalue `auto_ptr<V>'.
|> >
|> >It doesn't quite seem to like the fact that the copy-assignment and copy-ctor
|> >operators take non-const parameters.

|> That warning is not bogus; on the contrary, the code is ill-formed,
|> and the draft standard *requires* a diagnostic.
|> (5.2.2/3 says that argument passing is treated as initialization,
|> and 8.5.3/8 says you can't initialize a non-const reference with
|> an rvalue.)

To which Michael Cook (mcook@cognex.com) responded:

|> Hmm.  Interesting.  That means the auto_ptr class can't be used that way.
|> That surprises me.

It not only surprises me, it bothers me profoundly.  I find the
parameter declaration of auto_ptr<T>::operator= particularly
problematic.  On one hand, the right hand side of assignment definitly
*is* modified; declaring it const (and casting away const in operator=
is order to implement the current semantics) would be outright lying to
the user.  It is also lying to the compiler; presumably at some future
date, a compiler will take advantage of this const declaration in order
to implement some fancy optimization, which will break in the case of
casting away const.

On the other hand, using an auto_ptr as the return value of a function
would seem to be one of its principal uses.  Not allowing this would
almost render auto_ptr useless.

My current solution (in my personal implementation) is to declare the
parameter of operator= const, with *big* warnings in comments at the
point of declaration that this is a lie, and to declare the pointer
member mutable, so as to tell the compiler that the const may be a lie.
Hardly what I would call ideal, but the best I've been able to come up
with til yet.

Does anyone have any other solutions, or suggestions as to what the
standard *should* say?
-- 
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.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2077
Author: Fergus Henderson
Date: Sat, 30 Sep 1995 14:03
86 lines
4134 bytes
kanze@gabi-soft.fr (J. Kanze) writes:

>Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
>|> Michael Cook <mcook@cognex.com> writes:
>
>|> >    auto_ptr<V> byValue(auto_ptr<V> a);
>|> >    a = byValue(b);
>|> >    //   warning: initialization of non-const `auto_ptr<V> &' from
>|> >    //   rvalue `auto_ptr<V>'.
>
>|> That warning is not bogus; on the contrary, the code is ill-formed,
>|> and the draft standard *requires* a diagnostic.
>|> (5.2.2/3 says that argument passing is treated as initialization,
>|> and 8.5.3/8 says you can't initialize a non-const reference with
>|> an rvalue.)
>
>To which Michael Cook (mcook@cognex.com) responded:
>
>|> Hmm.  Interesting.  That means the auto_ptr class can't be used that way.
>|> That surprises me.
>
>It not only surprises me, it bothers me profoundly. I find the
>parameter declaration of auto_ptr<T>::operator= particularly
>problematic. 

Yes, I agree: I too find the auto_ptr assignment operator very disturbing,
though possibly for slightly different reasons.  I don't like the semantics
of the assignment operator: it does not just copy the auto_ptr, it
also invalidates the source of the copy.  I think that using `operator ='
for this operation is an abuse of operator overloading.

>On one hand, the right hand side of assignment definitly
>*is* modified; declaring it const (and casting away const in operator=
>is order to implement the current semantics) would be outright lying to
>the user.  It is also lying to the compiler; presumably at some future
>date, a compiler will take advantage of this const declaration in order
>to implement some fancy optimization, which will break in the case of
>casting away const.

Right.  This would awful; certainly much worse than the current situation.

>On the other hand, using an auto_ptr as the return value of a function
>would seem to be one of its principal uses.  Not allowing this would
>almost render auto_ptr useless.

I don't think so.  Instead of returning an auto_ptr<T>, you can
just return the T* obtained from a call to auto_ptr<T>::release().
The caller can use this T* to initialize another auto_ptr<T>.

>My current solution (in my personal implementation) is to declare the
>parameter of operator= const, with *big* warnings in comments at the
>point of declaration that this is a lie, and to declare the pointer
>member mutable, so as to tell the compiler that the const may be a lie.
>Hardly what I would call ideal, but the best I've been able to come up
>with til yet.

This is an awful abuse of both `mutable' and `const', and a horrible
hack, IMHO.  I wouldn't recommend it.

>Does anyone have any other solutions, or suggestions as to what the
>standard *should* say?

I think the assignment operator and copy-constructor of auto_ptr
ought to be declared private.  If you want to copy an auto_ptr,
then instead of writing

	auto_ptr<T> y = x;	// copy constructor
	y = x;			// assignment operator


you should have to write

	auto_ptr<T> y = x.release();
	y = x.release();

This makes it clear that x is being modified.

-- 
Fergus Henderson             |  "Australia is the richest country in the world,
fjh@cs.mu.oz.au              |   according to a new system of measuring wealth
http://www.cs.mu.oz.au/~fjh  |   announced by the World Bank yesterday."
PGP: finger fjh@128.250.37.3 |  - Melbourne newspaper "The Age", 18 Sept 1995.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2087
Author: Lars Farm
Date: Mon, 02 Oct 1995 15:46
54 lines
2169 bytes
In article <9527400.19710@mulga.cs.mu.OZ.AU>,
fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:

>I think the assignment operator and copy-constructor of auto_ptr
>ought to be declared private.  If you want to copy an auto_ptr,
>then instead of writing
>
>	auto_ptr<T> y = x;	// copy constructor
>	y = x;			// assignment operator
>
>
>you should have to write
>
>	auto_ptr<T> y = x.release();
>	y = x.release();
>
>This makes it clear that x is being modified.

Nowhere else in a c++ program will a valid ptr_a become invalid by:

  ptr_b = ptr_a;

Nowhere else in a c++ (or any other) program will the rhs be altered by
assignment.

If I really want to transfer ownership I can do
ptr_b.reset(ptr_a.release()); If I'm unaware of the danger, the compiler
will point me in the right direction. As it stands it will be quite hard to
explain to students why this must behave so counterintuitively. IMHO the
simpler version with private copy/op= will also be easier to use.

Also:

void f( auto_ptr<X> ); // this might not make sense (to you), 
                       // but you must be aware of the dangers 
                       // with auto_ptr to know... many wont be
void g()
{
   auto_ptr<X> x( new X );
   ...
   x->m     // x is valid
   f( x );
   x->m;    // oops... compiler would catch this with private copy-ctor

I think they should be private.

--
Lars Farm, lars.farm@nts.mh.se

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2091
Author: Bill Gibbons
Date: Mon, 02 Oct 1995 20:28
59 lines
2810 bytes
In article <9527400.19710@mulga.cs.mu.OZ.AU>, fjh@munta.cs.mu.OZ.AU
(Fergus Henderson) wrote:

> I don't think so.  Instead of returning an auto_ptr<T>, you can
> just return the T* obtained from a call to auto_ptr<T>::release().
> The caller can use this T* to initialize another auto_ptr<T>.

This is very risky.  The whole point of auto_ptr is that it makes code
which handles allocated objects behave well when exceptions propagate
through the scope using the pointer.  To make this work well there are
two very strict requirements:

   * The raw pointer must *always* be owned by some auto_ptr.

   * The raw pointer must *never* be owned by more than one auto_ptr.

Any time you discard the auto_ptr and pass around the raw pointer you
violate the first requirement.  Any time you initialize an auto_ptr with
a raw pointer which belongs to another auto_ptr you violate the second
requirement.

For example:

    struct X { ~X() { throw "oops!"; } };

    T * unsafe_function() {
        auto_ptr<T> p = new T;
        X x;
        return p.release();
    }

Sequence of events:

  (1) The pointer is released, making the function vulnerable.
  (2) "x" is destroyed, causing an exception to be thrown.
  (3) "p" is destroyed, but "p" no longer holds the pointer.
  (4) "unsafe_function" exits with a memory leak.

The interesting cases for assignment and initialization are not uses of
local variables in the same scope, but rather passing arguments to
functions and returning values from functions.  In these contexts it is
necessary to either violate the above requirements (in which case the
program isn't exception-safe) or deal with transfer of ownership directly
in the assignment operator and copy constructor.

Taligent has had years of experience using a variety of templates which
are variants of auto_ptr.  The consensus here is that auto_ptr must have
ownership semantics, and they must be enforced by the assignment operator
and copy constructor.

-- 
Bill Gibbons
bgibbons@taligent.com

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2093
Author: J. Kanze
Date: Tue, 03 Oct 1995 02:25
118 lines
6036 bytes
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
|> kanze@gabi-soft.fr (J. Kanze) writes:

|> >Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
|> >|> Michael Cook <mcook@cognex.com> writes:
|> >
|> >|> >    auto_ptr<V> byValue(auto_ptr<V> a);
|> >|> >    a = byValue(b);
|> >|> >    //   warning: initialization of non-const `auto_ptr<V> &' from
|> >|> >    //   rvalue `auto_ptr<V>'.
|> >
|> >|> That warning is not bogus; on the contrary, the code is ill-formed,
|> >|> and the draft standard *requires* a diagnostic.
|> >|> (5.2.2/3 says that argument passing is treated as initialization,
|> >|> and 8.5.3/8 says you can't initialize a non-const reference with
|> >|> an rvalue.)
|> >
|> >To which Michael Cook (mcook@cognex.com) responded:
|> >
|> >|> Hmm.  Interesting.  That means the auto_ptr class can't be used that way.
|> >|> That surprises me.
|> >
|> >It not only surprises me, it bothers me profoundly. I find the
|> >parameter declaration of auto_ptr<T>::operator= particularly
|> >problematic. 

|> Yes, I agree: I too find the auto_ptr assignment operator very disturbing,
|> though possibly for slightly different reasons.  I don't like the semantics
|> of the assignment operator: it does not just copy the auto_ptr, it
|> also invalidates the source of the copy.  I think that using `operator ='
|> for this operation is an abuse of operator overloading.

After reading your posting, I agree.  This is really the cause of the
problem.  Operator= (and copy construction) has generally accepted
semantics.  The operator= of auto_ptr does not follow these semantics.

|> >On one hand, the right hand side of assignment definitly
|> >*is* modified; declaring it const (and casting away const in operator=
|> >is order to implement the current semantics) would be outright lying to
|> >the user.  It is also lying to the compiler; presumably at some future
|> >date, a compiler will take advantage of this const declaration in order
|> >to implement some fancy optimization, which will break in the case of
|> >casting away const.

|> Right.  This would awful; certainly much worse than the current situation.

|> >On the other hand, using an auto_ptr as the return value of a function
|> >would seem to be one of its principal uses.  Not allowing this would
|> >almost render auto_ptr useless.

|> I don't think so.  Instead of returning an auto_ptr<T>, you can
|> just return the T* obtained from a call to auto_ptr<T>::release().
|> The caller can use this T* to initialize another auto_ptr<T>.

This is awful.  Returning an auto_ptr guarantees that the memory is on
the heap.  A T* contains no such guarantee, and a T* returned from a
function should not be used to initialize an auto_ptr. <grin>

Seriously, there is a part of truth in what I say above.  I detest the
idiom in which functions return pointers to the heap, and expect the
caller to delete them.  I was hoping that auto_ptr would solve this
problem in an elegant way.

Oh well, back to my old RefCntPtr<T> class.

|> >My current solution (in my personal implementation) is to declare the
|> >parameter of operator= const, with *big* warnings in comments at the
|> >point of declaration that this is a lie, and to declare the pointer
|> >member mutable, so as to tell the compiler that the const may be a lie.
|> >Hardly what I would call ideal, but the best I've been able to come up
|> >with til yet.

|> This is an awful abuse of both `mutable' and `const', and a horrible
|> hack, IMHO.  I wouldn't recommend it.

I only recommend it as the lessor of two evils, but you've almost
convinced me to eshew auto_ptr completely.  Which is a shame, because I
very much like what the class is trying to do.

|> >Does anyone have any other solutions, or suggestions as to what the
|> >standard *should* say?

|> I think the assignment operator and copy-constructor of auto_ptr
|> ought to be declared private.  If you want to copy an auto_ptr,
|> then instead of writing

|> 	auto_ptr<T> y = x;	// copy constructor
|> 	y = x;			// assignment operator


|> you should have to write

|> 	auto_ptr<T> y = x.release();
|> 	y = x.release();

|> This makes it clear that x is being modified.

I agree with this for general use.  The problem is function return
values.  OK, the object in question is being modified, although you
promissed (with const) not to.  But since the object in question ceases
to exist immediatly after the modification, who cares? :-)

Ideally, perhaps, I would want to have assignment and copy construction
defined only when the source is a temporary.  In practice, in my own
code, I find that in fact, all (or almost all) of the assignments and
copies are in fact from temporaries.  (Off hand, I cannot remember any
that wasn't either a function return value, or a parameter to a
function.)  So I find that my solution, while ugly WRT C++ programming,
does correspond to what I expect an auto_ptr to do.
-- 
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.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2100
Author: J. Kanze
Date: Tue, 03 Oct 1995 13:22
23 lines
1710 bytes
Bill Gibbons (bgibbons@taligent.com) wrote:

|> Taligent has had years of experience using a variety of templates which
|> are variants of auto_ptr.  The consensus here is that auto_ptr must have
|> ownership semantics, and they must be enforced by the assignment operator
|> and copy constructor.

While I've certainly less experience than Taligent, this was my feeling,
too.

So how do you do it: as I do, by casting away const in the assignment
operator and the copy constructor, or do you have some other trick?  (I
would love to find a better solution, since I think that Fergus'
concerns about this solution *are* valid.)
-- 
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.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2101
Author: Dag Bruck
Date: Tue, 03 Oct 1995 14:46
33 lines
2179 bytes
Bill Gibbons <bgibbons@taligent.com> wrote:
>
>   * The raw pointer must *always* be owned by some auto_ptr.
>
>   * The raw pointer must *never* be owned by more than one auto_ptr.
>.....
>Taligent has had years of experience using a variety of templates which
>are variants of auto_ptr.  The consensus here is that auto_ptr must have
>ownership semantics, and they must be enforced by the assignment operator
>and copy constructor.

The requirements for exception-safe programs are very important, and I
agree that auto_ptr should have ownership semantics.  However, it does
not follow that these semantics should be implemented with the assignment
operator and the copy-constructor.

Because of the confusion, op= and the copy-ctor should be unimplemented
(private) and the transfer of ownership implemented with some other
function.  (This is also one of the Swedish Committee Draft Ballot
comments.)

Dag Bruck

-- 
Dynasim AB                            Phone:  +46 46 182500
Research Park Ideon                   Fax:    +46 46 129879
S-223 70 Lund                         E-mail: Dag@Dynasim.se
Sweden                                URL:    http://www.dynasim.se


[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2135
Author: Colin Chambers
Date: Fri, 06 Oct 1995 15:03
32 lines
1961 bytes
In article: <44thrj$kid@gabi.gabi-soft.fr>  kanze@gabi-soft.fr (J. Kanze) writes:
> Dag Bruck (dag@net.dynasim.se) wrote:
> |> Because of the confusion, op= and the copy-ctor should be unimplemented
> |> (private) and the transfer of ownership implemented with some other
> |> function.  (This is also one of the Swedish Committee Draft Ballot
> |> comments.)
> 
> So how do you handle transfer of ownership in return values?
> 

If op= and the copy-ctor are unimplemented then it is probably inappropriate
to have a function that returns an auto_ptr<>.  It seems to me that this is not
a great loss as the same end result can still be achieved, albeit with different syntax,
by using a (possibly const) auto_ptr<> reference or pointer argument.  For example

	void f(auto_ptr<T>& p) { p.reset(new T); }

	void g()
	{
		auto_ptr<T> p;
		f(p);
		...
	}
	
-- 
Colin Chambers
cc@lagan.com


[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: : reset and auto_ptr::operator=
#2147
Author: Fergus Henderson
Date: Sat, 07 Oct 1995 21:21
57 lines
2913 bytes
bgibbons@taligent.com (Bill Gibbons) writes:

>fjh@munta.cs.mu.OZ.AU (Fergus Henderson) wrote:
>
>> I don't think so.  Instead of returning an auto_ptr<T>, you can
>> just return the T* obtained from a call to auto_ptr<T>::release().
>> The caller can use this T* to initialize another auto_ptr<T>.
>
>This is very risky.

You are right, my suggestion above wouldn't work.

>Taligent has had years of experience using a variety of templates which
>are variants of auto_ptr.  The consensus here is that auto_ptr must have
>ownership semantics, and they must be enforced by the assignment operator
>and copy constructor.

So what do Taligent's auto_ptr-like classes do about the problem
that the assignment operator modifies its argument, but its argument
must be a const reference so that it can accept a temporary, such as
a function return value? 

I can see several options:

	(1) declare the assignment operator to take a non-const reference;
	    this is what the April draft does, but as James Kanze said, it
	    seems to make auto_ptr useless for returning values from functions.

	(2) declare the pointer field of auto_ptr as `mutable'

	(3) cast-away-const in the assignment operator
	    This is similar to using `mutable', but less safe,
	    since one day someone will try to use a genuinely
	    const auto_ptr, and the compiler will place it in ROM.

	(4) use an extra level of indirection

Now that you have pointed out the problem with my earlier suggestion,
and having considered the issue further, I think I must agree that
(mis)using `mutable' may be the best option.

Of course, there are a couple of other options:

	(5) don't use auto_ptr, use a reference counted pointer instead

	(6) use garbage collection! ;-)

-- 
Fergus Henderson             |  "Australia is the richest country in the world,

fjh@cs.mu.oz.au              |   according to a new system of measuring wealth
http://www.cs.mu.oz.au/~fjh  |   announced by the World Bank yesterday."
PGP: finger fjh@128.250.37.3 |  - Melbourne newspaper "The Age", 18 Sept 1995.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: :reset and auto_ptr::operator=
#2149
Author: Dag Bruck
Date: Mon, 09 Oct 1995 09:40
42 lines
2129 bytes
J. Kanze <kanze@gabi-soft.fr> wrote:
>
>Dag Bruck (dag@net.dynasim.se) wrote:
>
>> Because of the confusion, op= and the copy-ctor should be unimplemented
>> (private) and the transfer of ownership implemented with some other
>> function.  (This is also one of the Swedish Committee Draft Ballot
>> comments.)
>
>So how do you handle transfer of ownership in return values?

The answer is simple, but perhaps not acceptable: you would have to return
values through a reference argument.

Alternatively, you need a helper class, something like:

	template <class T>
	struct auto_ptr_value {
		operator auto_ptr<T> ();
		auto_ptr_value(const auto_ptr_value &);
	private:
		// .....
	};

	template <class T>
	auto_ptr_value<T> auto_ptr<T>::make_copy()
	{
		// create auto_ptr_value somehow
	}

Is it worth it?

Dag Bruck
-- 
Dynasim AB                            Phone:  +46 46 182500
Research Park Ideon                   Fax:    +46 46 129879
S-223 70 Lund                         E-mail: Dag@Dynasim.se
Sweden                                URL:    http://www.dynasim.se
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: : reset and auto_ptr::operator=
#2278
Author: Fergus Henderson
Date: Sun, 22 Oct 1995 07:03
28 lines
1599 bytes
kanze@gabi-soft.fr (J. Kanze) writes:

>Actually, it occurs to me that the following does work:
>
>    auto_ptr< T >       f() ;
>    auto_ptr< T >       p1( f().release() ) ;
>	auto_ptr< T >		p2 ;
>	p2.reset( f().release() ) ;
>
>Somehow, it just doesn't seem natural, though. 

It seems fine to me.

It certainly seems more natural than assignment operators that
clobber the right-hand operand.

-- 
Fergus Henderson             |  "Australia is the richest country in the world,
fjh@cs.mu.oz.au              |   according to a new system of measuring wealth
http://www.cs.mu.oz.au/~fjh  |   announced by the World Bank yesterday."
PGP: finger fjh@128.250.37.3 |  - Melbourne newspaper "The Age", 18 Sept 1995.


---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr: : reset and auto_ptr::operator=
#2297
Author: Eric Biederman
Date: Wed, 25 Oct 1995 02:39
27 lines
1875 bytes
Someone writes:
   >Actually, it occurs to me that the following does work:
   >
   >    auto_ptr< T >       f() ;
   >    auto_ptr< T >       p1( f().release() ) ;
   >	auto_ptr< T >		p2 ;
   >	p2.reset( f().release() ) ;
   >
   >Somehow, it just doesn't seem natural, though. 

There is a case where it doesn't work.

The problem is that you are passing it as a standard pointer type.
What happens if you were to run out of stack after the call to release
and before the call to the constructor, or reset.  And an exception is
thrown.

If your program actualy catches that exception then a memory leak has
occured. ( A rare case I will admit).

There are probably more realistic examples is less mundane code.

It must be in an object at all times TO BE SAFE!
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
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