🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

17 total messages Started by ian (i.) willmott Tue, 31 Oct 1995 21:25
auto_ptr<T> as function return type
#2373
Author: ian (i.) willmott
Date: Tue, 31 Oct 1995 21:25
24 lines
1429 bytes
Some recent comments in this newsgroup indicate that there is some problem with
returning an auto_ptr from a function. I was not aware of this; the April 1995
working paper does not mention it and it is not obvious to me why there should
be a problem other than the overhead of constructing and destroying a temporary
object. Could somebody better informed than I am explain what the issue is? My
apologies if this has been discussed before; I missed it.

Also, could somebody post the procedure for submitting comments on the draft
standard? I sent email to 'c++std-notify@research.att.com' in July and got back
a receipt acknowledgement, but nothing else ever came. Again, I expect that
this has been posted before, but I didn't see it. Thanks.

Ian Willmott
Bell-Northern Research
Ottawa, Canada
(613)-763-9688
willmott@bnr.ca


---
[ 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<T> as function return type
#2376
Author: Matt Austern
Date: Wed, 01 Nov 1995 00:04
29 lines
2237 bytes
In article <47616o$lvr@bcarh8ab.bnr.ca> "ian (i.) willmott" <willmott@bnr.ca> writes:

> Some recent comments in this newsgroup indicate that there is some
> problem with returning an auto_ptr from a function. I was not aware
> of this; the April 1995 working paper does not mention it and it is
> not obvious to me why there should be a problem other than the
> overhead of constructing and destroying a temporary object.

The problem is that the argument of auto_ptr's operator= and copy
constructor is a non-const reference, rather than a const reference.
(And that's entirely proper, since an expression like "p2 = p1" really
does modify p1; calling the argument of operator= a const reference
would be a lie.)

If a function returns an auto_ptr as an rvalue, it can't be used as
the argument to a function that expects a non-const reference.  There
are ways to get around this, but they're all a bit clumsy.

I don't know of any simply way to modify the definition of auto_ptr in
the standard to avoid this difficulty: it seems to follow from the
semantics of strict ownership.
-- 
  Matt Austern                             He showed his lower teeth.  "We 
  matt@physics.berkeley.edu                all have flaws," he said, "and 
  http://dogbert.lbl.gov/~matt             mine is being wicked."

[ 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<T> as function return type
#2380
Author: David Vandevoorde
Date: Wed, 01 Nov 1995 03:54
31 lines
1840 bytes
>>>>> "IW" ==   <ian> writes:
IW> Some recent comments in this newsgroup indicate that there is some
IW> problem with returning an auto_ptr from a function. I was not
IW> aware of this; the April 1995 working paper does not mention it
IW> and it is not obvious to me why there should be a problem other
IW> than the overhead of constructing and destroying a temporary
IW> object. Could somebody better informed than I am explain what the
IW> issue is? My apologies if this has been discussed before; I missed
IW> it.
[...]

AFAIK, the problem is not so much with returning an auto_ptr as
what can be done with the return value (not much). The signatures 
of the copy constructors and operator='s (which take non-const 
auto_ptr's) are incompatible with the rvalue character of function
return values.

Hence,

	auto_ptr<double> f();
	auto_ptr<double> p(f()); 	// Ah no, copy-ctor take 
					// non-const reference :(
and similarly:
	auto_ptr<double> p;
	p = f();	// Trouble again...

	Daveed
---
[ 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<T> as function return type
#2379
Author: Fergus Henderson
Date: Wed, 01 Nov 1995 13:22
34 lines
1593 bytes
vandevod@cs.rpi.edu (David Vandevoorde) writes:

>AFAIK, the problem is not so much with returning an auto_ptr as
>what can be done with the return value (not much). The signatures 
>of the copy constructors and operator='s (which take non-const 
>auto_ptr's) are incompatible with the rvalue character of function
>return values.
>
>Hence,
>
>	auto_ptr<double> f();
>	auto_ptr<double> p(f()); 	// Ah no, copy-ctor take 
>					// non-const reference :(
>and similarly:
>	auto_ptr<double> p;
>	p = f();	// Trouble again...

Yep.  With the current spec., you need to write

	auto_ptr<double> p(f().release());

and

	p.reset(f().release());

instead.

--
Fergus Henderson             	WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au              	PGP: finger fjh@128.250.37.3
---
[ 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<T> as function return type
#2394
Author: David Vandevoorde
Date: Wed, 01 Nov 1995 21:59
24 lines
1327 bytes
>>>>> "FH" == Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
[...]
FH> Yep.  With the current spec., you need to write
FH> 	auto_ptr<double> p(f().release());

Indeed... and the more I look at it, the more I like it :-P

FH> and
FH> 	p.reset(f().release());

...but here I'm not sure; I think I'd rather see

	p = f().release();

and do away with the get() member.

	Daveed

	[I agree. -fjh.]

---
[ 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<T> as function return type
#2406
Author: Stein Somers
Date: Thu, 02 Nov 1995 23:25
41 lines
1997 bytes
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
: Yep.  With the current spec., you need to write

: 	auto_ptr<double> p(f().release());

: and

: 	p.reset(f().release());

: instead.

This has been mentioned earlier, of course.  So I'd like to repost
this recent uncountered reply:

Eric Biederman (ebiederm@cse.unl.edu) wrote:
: 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.

Maybe when an object containing many auto_ptr's is returned, in which
case the auto_ptr's must be moved jointly?

: It must be in an object at all times TO BE SAFE!

Any remarks, please?


Stein Somers (somers@intec.rug.ac.be)
INTEC - IMEC/University of Gent, Belgium
---
[ 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<T> as function return type
#2408
Author: Fergus Henderson
Date: Fri, 03 Nov 1995 03:22
53 lines
2652 bytes
Stein Somers writes:

>Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
>: 	auto_ptr<double> p(f().release());
>: 	p.reset(f().release());
>
>This has been mentioned earlier, of course.  So I'd like to repost
>this recent uncountered reply:
>
>Eric Biederman (ebiederm@cse.unl.edu) wrote:
>: 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).

What makes you think an exception will be thrown in this case?

The draft standard certainly doesn't require implementations to
throw an exception if they run out of stack space, and I don't
know of any implementations that do so.

In any case, exactly the same problem could occur inside the
copy-constructor or assignment operator for auto_ptr! 
So your example doesn't seem to show any reason against using
release().

If there really was a problem with using release(), we could
go back to the earlier suggestion of using a transfer() function
which returned an enapsulated pointer.

>: There are probably more realistic examples is less mundane code.

I remain unconvinced.

>Maybe when an object containing many auto_ptr's is returned, in which
>case the auto_ptr's must be moved jointly?

Anything wrong with just returning an auto_ptr to a dynamically 
allocated object (containing many auto_ptrs), rather than returning
it by value?

--
Fergus Henderson             	WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au              	PGP: finger fjh@128.250.37.3
---
[ 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<T> as function return type
#2409
Author: James Kanze US/ESC 60/3/141 #407...
Date: Fri, 03 Nov 1995 12:12
74 lines
3365 bytes
In article <47b1um$fvs@infoserv.rug.ac.be>
uunet!PROBLEM_WITH_INEWS_GATEWAY_FILE!somers@ncar.UCAR.EDU (Stein
Somers) writes:

|> Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
|> : Yep.  With the current spec., you need to write

|> : 	auto_ptr<double> p(f().release());

|> : and

|> : 	p.reset(f().release());

|> : instead.

|> This has been mentioned earlier, of course.  So I'd like to repost
|> this recent uncountered reply:

|> Eric Biederman (ebiederm@cse.unl.edu) wrote:
|> : 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.

|> Maybe when an object containing many auto_ptr's is returned, in which
|> case the auto_ptr's must be moved jointly?

Very good point.  Having a copy constructor which takes a non-const
parameter means that in any object which contains (or inherits from)
an auto_ptr:

1) The compiler generated copy constructor will also have a non-const
parameter (as will the compiler generated assignment operator).  This
means that if you do not provide a copy constructor/assignment
operator yourself for your class, it `inherits' the problems of
auto_ptr with regards to being used as a return value.

2) If you wish to provide your own copy constructor/assignment
operator, either you declare the parameter non-const (with the
inherent problems), or you are forced to cast away const in your
function in order to transfer ownership.

|> : It must be in an object at all times TO BE SAFE!

|> Any remarks, please?

I fully agree with the above statement.  The whole point of auto_ptr
is that the object is put into an auto_ptr immediatly after creation,
and is in an auto_ptr at all times.  Any tricks involving removing it
from one auto_ptr, and later putting it in another, are just that:
tricks, and introduce an element of danger.  The purpose of auto_ptr
is precisely to eliminate this danger.
--

James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-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<T> as function return type
#2417
Author: eddy Gorsuch
Date: Fri, 03 Nov 1995 18:11
33 lines
2149 bytes
In article <47b1um$fvs@infoserv.rug.ac.be>,
Stein Somers <uunet!PROBLEM_WITH_INEWS_GATEWAY_FILE!somers@ncar.UCAR.EDU> wrote
:
[...]
>This has been mentioned earlier, of course.  So I'd like to repost
>this recent uncountered reply:
>
>Eric Biederman (ebiederm@cse.unl.edu) wrote:
>: 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.

Ummm, who throws an exception if you run out of stack? I thought that came
in as a signal (or other hardware error), not as a C++ exception.

By the same token, what happens if you allocate some storage, then run
out of stack space while trying to call the auto_ptr's constructor (or
reset())? This leaves the same memory leak. I don't think these cases are
(nor should they be) covered by the C++ standard. They are too machine/OS
dependant.

eddy
-- 
ed.dy \'ed-e-\ n [ME (Sc dial.) ydy, prob. fr. ON itha; akin to OHG ith- 
   again], L et and 1a: a current of water or air running contrary to the main 

   current; esp)X : a small whirlpool 1b: a substance moving similarly  2: a 
   contrary or circular current  - eddy vb
---
[ 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<T> as function return type
#2428
Author: Eric Biederman
Date: Sun, 05 Nov 1995 09:15
61 lines
3579 bytes
In article <47c7pe$722@eclipse.eng.sc.rolm.com> eddy@clipper.robadome.com
(eddy Gorsuch) writes:
   In article <47b1um$fvs@infoserv.rug.ac.be>,
   Stein Somers <uunet!PROBLEM_WITH_INEWS_GATEWAY_FILE!somers@ncar.UCAR.EDU>
   wrote:
   [...]
   >This has been mentioned earlier, of course.  So I'd like to repost
   >this recent uncountered reply:
   >
   >Eric Biederman (ebiederm@cse.unl.edu) wrote:
   >: 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.
[ hiden cut ]

   Ummm, who throws an exception if you run out of stack? I thought that came
   in as a signal (or other hardware error), not as a C++ exception.

[note: the useful way would for the signal to throw an exception.  It
       is an error appropriate to an exception. ] 
[note: who throws exceptions, _now_? ] 

Sorry, that was a bad example so acknowledged in a part you cut out.
A more realistic example happens if a signal handler is called
asynchronously.  It just happens that that happened while the call to
the autoptr's constructor or member reset was being formed upon the
stack.  This ill timed call to the signal code then throws an
exception.  Oops memory leak!

On the other hand if the memory was continually in an autoptr it would
be _safe_ from this (assuming the internal code for autoptr assignment
was written carefully, to avoid these kinds of problems).

   By the same token, what happens if you allocate some storage, then run
   out of stack space while trying to call the auto_ptr's constructor (or
   reset())? This leaves the same memory leak. I don't think these cases are
   (nor should they be) covered by the C++ standard. They are too machine/OS
   dependant.
[ ... ]

But that's transfering a pointer into an autoptr, the pointer makes no
guarantees of safety in that case.  But the __autoptr__ does!

Returning the autoptr to a normal pointer violates all gaurantes of
safety.  Assuming that you will still have safety is bad. It's as bad
as assuming all objects can be aligned on any address, or the bit
pattern of static_cast<void *>(0) is 0, or etc. 

Once your pointer is in autoptr it's _safe_.  While your pointer is in
autoptr it should remain _safe_.  

The issue of running out of stack space is not what I was arguing
about.  Simply my thought of a synchronous example that could cause
problems.  A very unrealistic example.

Eric
---
[ 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<T> as function return type
#2442
Author: John Barton
Date: Tue, 07 Nov 1995 04:33
33 lines
2305 bytes
In article <9511030943.AA23251@lts.sel.alcatel.de>, James Kanze US/ESC 60/3/141
 #40763 <kanze@lts.sel.alcatel.de> writes:
|> [delete some stuff]
|>                                    ...   The whole point of auto_ptr
|> is that the object is put into an auto_ptr immediatly after creation,
|> and is in an auto_ptr at all times.  Any tricks involving removing it
|> from one auto_ptr, and later putting it in another, are just that:
|> tricks, and introduce an element of danger.  The purpose of auto_ptr
|> is precisely to eliminate this danger.

  Nicely put.  Strict ownership is fundamentally incompatible with
auto_ptr<T> as function return type.  The latter implies ownership
by the returned temporary: lifetime control by a temporary is craziness.
(I have tried to beat this game myself several times).

   The way to use auto_ptr<T> successfully is to limit it to client
code.  Service providers write:
   // Callers own the lifetime of returned object; pick it up in an auto_ptr.
   Foo* doWorkAndCreateAFoo();
Clients pick up the result in auto del pointers:
   auto_ptr<Foo> my_foo(doWorkAndCreateFoo());
Anyone who fails to read and heed the comment loses.

--
John.

John J. Barton        jjb@watson.ibm.com            (914)784-6645
	<http://www.research.ibm.com/xw-SoftwareTechnology>
H1-C13 IBM Watson Research Center P.O. Box 704 Hawthorne NY 10598
---
[ 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<T> as function return type
#2449
Author: James Kanze US/ESC 60/3/141 #407...
Date: Tue, 07 Nov 1995 13:50
52 lines
3410 bytes
In article <47l6im$qu1@watnews2.watson.ibm.com> jjb@watson.ibm.com
(John Barton) writes:

|> In article <9511030943.AA23251@lts.sel.alcatel.de>, James Kanze US/ESC 60/3/
141
|>  #40763 <kanze@lts.sel.alcatel.de> writes:
|> |> [delete some stuff]
|> |>                                    ...   The whole point of auto_ptr
|> |> is that the object is put into an auto_ptr immediatly after creation,
|> |> and is in an auto_ptr at all times.  Any tricks involving removing it
|> |> from one auto_ptr, and later putting it in another, are just that:
|> |> tricks, and introduce an element of danger.  The purpose of auto_ptr
|> |> is precisely to eliminate this danger.

|>   Nicely put.  Strict ownership is fundamentally incompatible with
|> auto_ptr<T> as function return type.  The latter implies ownership
|> by the returned temporary: lifetime control by a temporary is craziness.
|> (I have tried to beat this game myself several times).

Put that way, it does sound crazy.  But I do it regularly with my
RefCntPtr class.  The temporary serves as a bridge between a local in
the called function (which has just gone out of scope), and a local in
the caller (which has yet to be initialized).  I would be interested
in hearing of examples where you have failed `to beat this game'.
Your statement worries me that there is a defect waiting to happen in
my own code.

|>    The way to use auto_ptr<T> successfully is to limit it to client
|> code.  Service providers write:
|>    // Callers own the lifetime of returned object; pick it up in an auto_ptr
.
|>    Foo* doWorkAndCreateAFoo();
|> Clients pick up the result in auto del pointers:
|>    auto_ptr<Foo> my_foo(doWorkAndCreateFoo());
|> Anyone who fails to read and heed the comment loses.

This fails on two counts:

1. The actual service provider may be several layers removed.  In
particular, an intermediate function may be used to `garnish' the
new'ed object before returning it to the client.  And presumably,
garnishing it could cause an exception.

2. As Bill Gibbons has pointed out, there is a window of opertunity at
the end of the server function in which the object may be lost.  While
I think that most people would agree that it is not a good idea to let
exceptions escape from destructors, good code - at least good library
code - will be robust even in this case.
---
[ 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<T> as function return type
#2450
Author: law
Date: Tue, 07 Nov 1995 13:52
35 lines
2402 bytes
In <47l6im$qu1@watnews2.watson.ibm.com>, jjb@watson.ibm.com (John Barton) write
s:
>  Nicely put.  Strict ownership is fundamentally incompatible with
>auto_ptr<T> as function return type.  The latter implies ownership
>by the returned temporary: lifetime control by a temporary is craziness.
>(I have tried to beat this game myself several times).
>
>   The way to use auto_ptr<T> successfully is to limit it to client
>code.  Service providers write:
>   // Callers own the lifetime of returned object; pick it up in an auto_ptr.
>   Foo* doWorkAndCreateAFoo();
>Clients pick up the result in auto del pointers:
>   auto_ptr<Foo> my_foo(doWorkAndCreateFoo());
>Anyone who fails to read and heed the comment loses.
>
>--
>John.

I'm confused, John.  You say "nicely put" but he said that objects
should be put into an auto_ptr<> immediately after creation.  Your code
certainly doesn't do that.

Your code is also a prescription for undeleted objects (despite the
comment).  What's crazy about returning an auto_ptr. aside from the
unnecessary restriction that it can't be used to assign to or construct
another auto_ptr directly?  And why is lifetime control by a "temporary"
fundamentally different than lifetime control by some named object?
The semantics of the two objects is the same, isn't it?  They just have
different lifetimes.

Bill Law
---
[ 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<T> as function return type
#2457
Author: John Max Skaller
Date: Wed, 08 Nov 1995 18:03
73 lines
3403 bytes
law@solution-frameworks.com wrote:
>In <47l6im$qu1@watnews2.watson.ibm.com>, jjb@watson.ibm.com (John Barton) write
>s:
>>  Nicely put.  Strict ownership is fundamentally incompatible with
>>auto_ptr<T> as function return type.  The latter implies ownership
>>by the returned temporary: lifetime control by a temporary is craziness.
>>(I have tried to beat this game myself several times).
>>
>>   The way to use auto_ptr<T> successfully is to limit it to client
>>code.  Service providers write:
>>   // Callers own the lifetime of returned object; pick it up in an auto_ptr.
>>   Foo* doWorkAndCreateAFoo();
>>Clients pick up the result in auto del pointers:
>>   auto_ptr<Foo> my_foo(doWorkAndCreateFoo());
>>Anyone who fails to read and heed the comment loses.
>>
>>--
>>John.
>
>I'm confused, John.  You say "nicely put" but he said that objects
>should be put into an auto_ptr<> immediately after creation.  Your code
>certainly doesn't do that.

   Yes it does. "doWorkAndCreateFoo()" is a factory function
and is used directly as the argument for "my_foo"s ctor.

>Your code is also a prescription for undeleted objects (despite the
>comment).  

   Thats the point: the constraints on correct use are 
indeed _prescribed_ (documented). Thats a heck of a lot better
than a lot of commercial libraries which talk all about
functionality and forget to mention ownership.

>What's crazy about returning an auto_ptr. aside from the
>unnecessary restriction that it can't be used to assign to or construct
>another auto_ptr directly?  And why is lifetime control by a "temporary"
>fundamentally different than lifetime control by some named object?

    Temporaries are rvalues and so non-const references cannot be
bound to them by non-member functions, so they cannot be
modified (without a const_cast<>), and so they cannot 
transfer ownership (which is a destructive operation).

    A solution is to provide a member function:

    struct auto_ptr { ...
       auto_ptr<T> &ref() { return *this; }
       ......
    };

and now:

    auto_ptr<int> f();
    auto_ptr<int> p(f().ref());

This is a way of converting a non-const rvalue into
a non-const lvalue. It is invasive (requires a member function)
but it is safe, which a const_cast<> is not.

-- 
John Max Skaller               voice: 61-2-566-2189
81 Glebe Point Rd              fax:   61-2-660-0850
GLEBE NSW 2037                 email: maxtal@suphys.physics.oz.au
AUSTRALIA                      email: skaller@maxtal.com.au



---
[ 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<T> as function return type
#2486
Author: J. Kanze
Date: Thu, 09 Nov 1995 19:23
36 lines
2015 bytes
John Max Skaller (maxtal@suphys.physics.su.oz.au) wrote:

|>     Temporaries are rvalues and so non-const references cannot be
|> bound to them by non-member functions, so they cannot be
|> modified (without a const_cast<>), and so they cannot 
|> transfer ownership (which is a destructive operation).

|>     A solution is to provide a member function:

|>     struct auto_ptr { ...
|>        auto_ptr<T> &ref() { return *this; }
|>        ......
|>     };

|> and now:

|>     auto_ptr<int> f();
|>     auto_ptr<int> p(f().ref());

|> This is a way of converting a non-const rvalue into
|> a non-const lvalue. It is invasive (requires a member function)
|> but it is safe, which a const_cast<> is not.

Just curious: in what way is this any safer than using a const_cast in
the implementation of auto_ptr<T>::operator=()?
-- 
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils, études et réalisations en logiciel orienté objet --
              -- A la recherche d'une activité dans une region francophone

---
[ 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<T> as function return type
#2539
Author: Sean A Corfield
Date: Mon, 13 Nov 1995 16:09
43 lines
2394 bytes
In article <47sm8h$4eh@gabi.gabi-soft.fr>,
kanze@gabi-soft.fr (J. Kanze) wrote:

|> Just curious: in what way is this any safer than using a const_cast in
|> the implementation of auto_ptr<T>::operator=()?

In Tokyo last week, Bill Gibbons suggested using a proxy nested class to
alleviate this problem. It works by having auto_ptr constructable from the
proxy object and assignable from the proxy object then having auto_ptr
convert to the proxy. Something like this:

  template<typename T> class auto_ptr {
    struct proxy {
      auto_ptr* p;
      proxy(auto_ptr* ap) : p(ap) { }
    };
  public:
    auto_ptr(const proxy& prox) : p(prox.p->p) { prox.p->p = 0; }
    // etc
    operator proxy() { return proxy(this); }
    // etc
  private:
    T* p;
  };

  auto_ptr<X> f();
  auto_ptr<X> p(f());
  // equivalent to:
  auto_ptr<X> p(f().operator proxy());

Similar code changes could be done for operator=. The committee have not
decided exactly what to do about fixing auto_ptr yet but they intend to do
_something_ in Scotts Valley...probably just make the parameter of the copy
constructor const and force the implementation to work around it with a
cast (ugh!).

Sean A. Corfield
Object Consultancy Services -- voting member of X3J16
C++ - Beyond the ARM http://uptown.turnpike.net/~scorf/cplusext.html
---
[ 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<T> as function return type
#2639
Author: Pablo Halpern
Date: Sat, 18 Nov 1995 20:10
75 lines
3284 bytes
Sean A Corfield <sean@corf.demon.co.uk> wrote:

>In Tokyo last week, Bill Gibbons suggested using a proxy nested class to
>alleviate this problem. It works by having auto_ptr constructable from the
>proxy object and assignable from the proxy object then having auto_ptr
>convert to the proxy. Something like this:
>
>  template<typename T> class auto_ptr {
>    struct proxy {
>      auto_ptr* p;
>      proxy(auto_ptr* ap) : p(ap) { }
>    };
>  public:
>    auto_ptr(const proxy& prox) : p(prox.p->p) { prox.p->p = 0; }
>    // etc
>    operator proxy() { return proxy(this); }
>    // etc
>  private:
>    T* p;
>  };
>
>
>  auto_ptr<X> f();
>  auto_ptr<X> p(f());
>  // equivalent to:
>  auto_ptr<X> p(f().operator proxy());
>
>Similar code changes could be done for operator=. 

Wouldn't it be more efficient to code the so-called "copy constructor"
using pass by value to avoid the extra unnamed temporary:

  auto_ptr(proxy prox) : p(prox.p->p) { prox.p->p = 0; }

This way, the generated code should be exactly as efficient as passing a
non-const auto_ptr by reference. My concern with both approaches is that
the WP does not actually consider the above to be true copy constructors
(although the ARM did). Thus, the compiler may generate its own copy
constructor for auto_ptr<T>, thus defeating the whole thing.

Just for completeness, I'll mention another solution, ugly as it is:

  template<typename T> class auto_ptr {
  public:
    auto_ptr() : pp(new T*(0)) { }  // pp = Pointer to null pointer
    auto_ptr(const auto_ptr<T>& rhs) : pp(new T*(*rhs.pp)) 
      { *rhs.pp = 0; }
    ~auto_ptr() { delete *pp; delete pp; } // double delete
    T* release() { T* p = *pp; *pp = 0; return p; }

    auto_ptr<T>& operator=(const auto_ptr<T>& rhs)
    {
      if (this == &rhs) return *this;
      delete *pp;
      *pp = *rhs.pp;
      *rhs.pp = 0;  // pp is const pointer to non-const pointer to T
      return *this;
    }
    
  private:
    T** pp;  // double indirection
  };

Of course, this is much less efficient, with all of the heap
manipulations and double-indirections, but I think it would work.
-------------------------------------------------------------
Pablo Halpern                   phalpern@truffle.ultranet.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. ]
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