Thread View: comp.std.c++
17 messages
17 total messages
Started by ian (i.) willmott
Tue, 31 Oct 1995 21:25
auto_ptr<T> as function return type
Author: ian (i.) willmott
Date: Tue, 31 Oct 1995 21:25
Date: Tue, 31 Oct 1995 21:25
24 lines
1429 bytes
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
Author: Matt Austern
Date: Wed, 01 Nov 1995 00:04
Date: Wed, 01 Nov 1995 00:04
29 lines
2237 bytes
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
Author: David Vandevoorde
Date: Wed, 01 Nov 1995 03:54
Date: Wed, 01 Nov 1995 03:54
31 lines
1840 bytes
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
Author: Fergus Henderson
Date: Wed, 01 Nov 1995 13:22
Date: Wed, 01 Nov 1995 13:22
34 lines
1593 bytes
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
Author: David Vandevoorde
Date: Wed, 01 Nov 1995 21:59
Date: Wed, 01 Nov 1995 21:59
24 lines
1327 bytes
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
Author: Stein Somers
Date: Thu, 02 Nov 1995 23:25
Date: Thu, 02 Nov 1995 23:25
41 lines
1997 bytes
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
Author: Fergus Henderson
Date: Fri, 03 Nov 1995 03:22
Date: Fri, 03 Nov 1995 03:22
53 lines
2652 bytes
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
Author: James Kanze US/ESC 60/3/141 #407...
Date: Fri, 03 Nov 1995 12:12
Date: Fri, 03 Nov 1995 12:12
74 lines
3365 bytes
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
Author: eddy Gorsuch
Date: Fri, 03 Nov 1995 18:11
Date: Fri, 03 Nov 1995 18:11
33 lines
2149 bytes
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
Author: Eric Biederman
Date: Sun, 05 Nov 1995 09:15
Date: Sun, 05 Nov 1995 09:15
61 lines
3579 bytes
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
Author: John Barton
Date: Tue, 07 Nov 1995 04:33
Date: Tue, 07 Nov 1995 04:33
33 lines
2305 bytes
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
Author: James Kanze US/ESC 60/3/141 #407...
Date: Tue, 07 Nov 1995 13:50
Date: Tue, 07 Nov 1995 13:50
52 lines
3410 bytes
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
Author: law
Date: Tue, 07 Nov 1995 13:52
Date: Tue, 07 Nov 1995 13:52
35 lines
2402 bytes
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
Author: John Max Skaller
Date: Wed, 08 Nov 1995 18:03
Date: Wed, 08 Nov 1995 18:03
73 lines
3403 bytes
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
Author: J. Kanze
Date: Thu, 09 Nov 1995 19:23
Date: Thu, 09 Nov 1995 19:23
36 lines
2015 bytes
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
Author: Sean A Corfield
Date: Mon, 13 Nov 1995 16:09
Date: Mon, 13 Nov 1995 16:09
43 lines
2394 bytes
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
Author: Pablo Halpern
Date: Sat, 18 Nov 1995 20:10
Date: Sat, 18 Nov 1995 20:10
75 lines
3284 bytes
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