scoped_ptr::release (again)

From http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm: "If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)" But there already is a way to escape the scope, via swap(). Would it make more sense to just provide release() and have users specify const if they want? (const scoped_ptr/scoped_array would effectively disallow swapping/releasing.) -- Yang Zhang http://www.mit.edu/~y_z/

On Feb 20, 2009, at 1:27 PM, Yang Zhang wrote:
From http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm :
"If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)"
But there already is a way to escape the scope, via swap().
Would it make more sense to just provide release() and have users specify const if they want? (const scoped_ptr/scoped_array would effectively disallow swapping/releasing.)
<opinion> http://home.roadrunner.com/~hinnant/unique_ptr03.html (search for "scoped_ptr") </opinion> -Howard

Howard Hinnant wrote:
On Feb 20, 2009, at 1:27 PM, Yang Zhang wrote:
From http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm:
"If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)"
But there already is a way to escape the scope, via swap().
Would it make more sense to just provide release() and have users specify const if they want? (const scoped_ptr/scoped_array would effectively disallow swapping/releasing.)
<opinion> http://home.roadrunner.com/~hinnant/unique_ptr03.html
(search for "scoped_ptr") </opinion>
Nice. Thanks for the pointer (pun intended). I take it boost does not have unique_ptr, correct? I checked in Boost.TR1 and found nothing. I did find boost::interprocess::unique_pointer, but that appears to be different. I did some digging, and I did find mention of this file on the gcc mailing lists - I take it this implementation is being included in GNU libstdc++? Lastly, I didn't see any rvalue references in this file. I was under the impression that the implementation of unique_ptr leverages rvalue references. Is this why there are const_casts present in the code? -- Yang Zhang http://www.mit.edu/~y_z/

On Feb 20, 2009, at 10:53 PM, Yang Zhang wrote:
Howard Hinnant wrote:
On Feb 20, 2009, at 1:27 PM, Yang Zhang wrote:
From http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm :
"If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)"
But there already is a way to escape the scope, via swap().
Would it make more sense to just provide release() and have users specify const if they want? (const scoped_ptr/scoped_array would effectively disallow swapping/releasing.) <opinion> http://home.roadrunner.com/~hinnant/unique_ptr03.html (search for "scoped_ptr") </opinion>
Nice. Thanks for the pointer (pun intended). I take it boost does not have unique_ptr, correct? I checked in Boost.TR1 and found nothing. I did find boost::interprocess::unique_pointer, but that appears to be different.
You might keep a close eye on boost::interprocess::unique_pointer. Ion knows what he's doing and is in sync with me. His version is probably changing to take advantage of a newly developed generic move emulation library that he's been working on, but I am not sure. I'm sure Ion will chime in. Whatever he says goes. I have 100% confidence in him in this matter. :-)
I did some digging, and I did find mention of this file on the gcc mailing lists - I take it this implementation is being included in GNU libstdc++?
I don't know.
Lastly, I didn't see any rvalue references in this file. I was under the impression that the implementation of unique_ptr leverages rvalue references. Is this why there are const_casts present in the code?
The referenced file is a pure C++03 emulation and doesn't contain C+ +0X code (e.g. rvalue references). The emulation is not perfect and so yes, const_cast is used to in some places to emulate (as much as possible) C++0X language features. A combined C++03/C++0X implementation is more likely to be found in a boost implementation such as boost::interprocess::unique_pointer (but I am not sure). -Howard

Yang Zhang skrev:
From http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm:
"If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)"
But there already is a way to escape the scope, via swap().
Would it make more sense to just provide release() and have users specify const if they want? (const scoped_ptr/scoped_array would effectively disallow swapping/releasing.)
FWIW, I think scoped_ptr/scoped_array should have a release() member. The defining aspects of std::auto_ptr is its ability to transfer ownership transparently, not that it has a release member. Especially when working with legacy code, release() is necessary. Therefore it is a great pity that the member is not provided. In my view this categorises as over-encapsulation. best regards Thorsten

Alexader wrote:
But there already is a way to escape the scope, via swap().
How ? I thought scoped_ptr was to prohibit swap either.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
WFM... void foo(scoped_array<int> &b) { scoped_array<int> a(new int[5]); swap(a,b); // escape } -- Yang Zhang http://www.mit.edu/~y_z/

Alexander wrote:
WFM...
void foo(scoped_array<int> &b) { scoped_array<int> a(new int[5]); swap(a,b); // escape }
Hm.. I agree with you that having swap to escape scoping but not having release looks inconsequent. In my opinion there should be no swap either. I use swap to do things like reallocate an array to a new size. I also use it to modify a linked list that uses scoped_ptr for its links.
swap() still guarantees that some code will delete the object or array at some point. I think leaks are impossible. Would release() do that? I'm unfamiliar with its function. If it means that the code that released the pointer is now responsible for deleting it, I don't want it. It will just mean that I have to examine all the code to look for releases and then see whether I can prove that code is guaranteed to delete it. The best thing about scoped_ptr and _array is that they are almost foolproof. The only ways that I can think of to mess one up are (a) to use the wrong one for the type of allocation (object or array) and (b) to get() its pointer and then delete it. That's my opinion as a long-time user. -- Dick Hadsell 203-992-6320 Fax: 203-992-6001 Reply-to: hadsell@blueskystudios.com Blue Sky Studios http://www.blueskystudios.com 1 American Lane, Greenwich, CT 06831-2560

On 23 Feb 2009, at 21:39, Richard Hadsell wrote:
WFM...
void foo(scoped_array<int> &b) { scoped_array<int> a(new int[5]); swap(a,b); // escape }
Hm.. I agree with you that having swap to escape scoping but not having release looks inconsequent. In my opinion there should be no swap either. I use swap to do things like reallocate an array to a new size. I also use it to modify a linked list that uses scoped_ptr for its
Alexander wrote: links.
swap() still guarantees that some code will delete the object or array at some point. I think leaks are impossible.
Would release() do that? I'm unfamiliar with its function. If it means that the code that released the pointer is now responsible for deleting it, I don't want it. It will just mean that I have to examine all the code to look for releases and then see whether I can prove that code is guaranteed to delete it.
The best thing about scoped_ptr and _array is that they are almost foolproof. The only ways that I can think of to mess one up are (a) to use the wrong one for the type of allocation (object or array) and (b) to get() its pointer and then delete it.
That's my opinion as a long-time user.
Could I suggest that if you want something like a scoped_ptr which you can return from functions, and release, then you probably want the slightly more powerful, but still very safe, unique_ptr? I'd vote for keeping scoped_ptr as simple as possible, even removing that swap, and directing people who want more power to unique_ptr. Chris

Christopher Jefferson wrote:
I'd vote for keeping scoped_ptr as simple as possible, even removing that swap, and directing people who want more power to unique_ptr.
I'd like to keep swap(). If the coder wants to disable it, wouldn't 'const scoped_ptr' suffice? If I have a class that supports assignment, and my class uses scoped_ptr to manage some resource, Herb Sutter's exception-safe assignment operator still applies: 1. Construct a new stack scoped_ptr with the incoming resource. An exception here leaves *this unmolested. 2. Swap the member scoped_ptr with the new scoped_ptr. (swap() is guaranteed not to throw.) 3. Leaving the assignment-operator method body destroys the temp stack scoped_ptr, releasing the member scoped_ptr's previous data.

AMDG Nat Goodspeed wrote:
Christopher Jefferson wrote:
I'd vote for keeping scoped_ptr as simple as possible, even removing that swap, and directing people who want more power to unique_ptr.
I'd like to keep swap(). If the coder wants to disable it, wouldn't 'const scoped_ptr' suffice?
If I have a class that supports assignment, and my class uses scoped_ptr to manage some resource, Herb Sutter's exception-safe assignment operator still applies:
1. Construct a new stack scoped_ptr with the incoming resource. An exception here leaves *this unmolested. 2. Swap the member scoped_ptr with the new scoped_ptr. (swap() is guaranteed not to throw.) 3. Leaving the assignment-operator method body destroys the temp stack scoped_ptr, releasing the member scoped_ptr's previous data.
The question is not whether swap is useful, but whether it should be part of scoped_ptr rather than another smart pointer. In Christ, Steven Watanabe

Steven Watanabe wrote:
Nat Goodspeed wrote:
If I have a class that supports assignment, and my class uses scoped_ptr to manage some resource...
The question is not whether swap is useful, but whether it should be part of scoped_ptr rather than another smart pointer.
Of course you're right. But if scoped_ptr is in all other ways the best tool for the job, should my class's requirement for an assignment operator force me to change to another smart pointer instead?

AMDG Nat Goodspeed wrote:
Steven Watanabe wrote:
Nat Goodspeed wrote:
If I have a class that supports assignment, and my class uses scoped_ptr to manage some resource...
The question is not whether swap is useful, but whether it should be part of scoped_ptr rather than another smart pointer.
Of course you're right.
But if scoped_ptr is in all other ways the best tool for the job, should my class's requirement for an assignment operator force me to change to another smart pointer instead?
Since swap already exists, it should certainly not be removed. If it didn't I could argue either way. As far as I am concerned, having to use a different smart pointer is not a problem per se as long as it doesn't introduce a performance penalty. (e.g. shared_ptr). The main issue is a keeping a consistent set of invariants. If we add all the "one little features" that anyone needs, the result will be to turn scoped_ptr into unique_ptr. In Christ, Steven Watanabe

2009/2/24 Steven Watanabe
AMDG
Nat Goodspeed wrote:
Christopher Jefferson wrote:
I'd vote for keeping scoped_ptr as simple as possible, even removing that swap, and directing people who want more power to unique_ptr.
I'd like to keep swap(). If the coder wants to disable it, wouldn't 'const scoped_ptr' suffice?
If I have a class that supports assignment, and my class uses scoped_ptr to manage some resource, Herb Sutter's exception-safe assignment operator still applies:
1. Construct a new stack scoped_ptr with the incoming resource. An exception here leaves *this unmolested. 2. Swap the member scoped_ptr with the new scoped_ptr. (swap() is guaranteed not to throw.) 3. Leaving the assignment-operator method body destroys the temp stack scoped_ptr, releasing the member scoped_ptr's previous data.
The question is not whether swap is useful, but whether it should be part of scoped_ptr rather than another smart pointer.
In Christ, Steven Watanabe
Which other smart pointer? Scoped_* is really simple and the optimized code is the same as a naked pointer, which is what some people need. For me, scoped_* is exactly what I need: - RAII - tantamount to a simple pointer - possible to swap pointers Matthieu -- Information System Engineer, Ph.D. Website: http://matthieu-brucher.developpez.com/ Blogs: http://matt.eifelle.com and http://blog.developpez.com/?blog=92 LinkedIn: http://www.linkedin.com/in/matthieubrucher

On 24 Feb 2009, at 19:26, Matthieu Brucher wrote:
2009/2/24 Steven Watanabe
: AMDG
Nat Goodspeed wrote:
Christopher Jefferson wrote:
I'd vote for keeping scoped_ptr as simple as possible, even removing that swap, and directing people who want more power to unique_ptr.
I'd like to keep swap(). If the coder wants to disable it, wouldn't 'const scoped_ptr' suffice?
If I have a class that supports assignment, and my class uses scoped_ptr to manage some resource, Herb Sutter's exception-safe assignment operator still applies:
1. Construct a new stack scoped_ptr with the incoming resource. An exception here leaves *this unmolested. 2. Swap the member scoped_ptr with the new scoped_ptr. (swap() is guaranteed not to throw.) 3. Leaving the assignment-operator method body destroys the temp stack scoped_ptr, releasing the member scoped_ptr's previous data.
The question is not whether swap is useful, but whether it should be part of scoped_ptr rather than another smart pointer.
In Christ, Steven Watanabe
Which other smart pointer? Scoped_* is really simple and the optimized code is the same as a naked pointer, which is what some people need. For me, scoped_* is exactly what I need: - RAII - tantamount to a simple pointer - possible to swap pointers
unique_ptr offers exactly that set too, along with: - possible to move pointers. - ability to use custom deleter if you want (I don't know if scoped_ptr offers that.. it is zero overhead if you don't use it). The only reasons to use scoped_ptr over unique_ptr, once it is present, will be if you don't want to be able to move things around. Probably the nicest feature of unique_ptr of scoped_ptr is that it can be returned from functions. Chris

I'm sorry if I'm a bit lame, but if you mean the boost::interprocess::unique_ptr; the deleter is not optional and if you mean std::unique_ptr... I can't find an implementation of it in boost. I don't know if it's supported in gcc yet... How am I to use it then?
unique_ptr offers exactly that set too, along with:
- possible to move pointers. - ability to use custom deleter if you want (I don't know if scoped_ptr offers that.. it is zero overhead if you don't use it).
The only reasons to use scoped_ptr over unique_ptr, once it is present, will be if you don't want to be able to move things around. Probably the nicest feature of unique_ptr of scoped_ptr is that it can be returned from functions.
Chris

2009/2/23 Alexander
WFM...
void foo(scoped_array<int> &b) { scoped_array<int> a(new int[5]); swap(a,b); // escape }
Hm.. I agree with you that having swap to escape scoping but not having release looks inconsequent. In my opinion there should be no swap either.
Without swap(), there will be need for another smart pointer. I use swap to swap two array pointers (so I'm using scoped_array) in my computations. Without it, I don't know how I would write it in an efficient way. Matthieu -- Information System Engineer, Ph.D. Website: http://matthieu-brucher.developpez.com/ Blogs: http://matt.eifelle.com and http://blog.developpez.com/?blog=92 LinkedIn: http://www.linkedin.com/in/matthieubrucher

I experienced a similar problem once with boost::shared_ptr<>. I've
solved it using:
boost::shared_ptr
From http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/scoped_ptr.htm:
"If scoped_ptr had a release() member, it would become possible to transfer ownership of the held pointer, weakening its role as a way of limiting resource lifetime to a given context. Use std::auto_ptr where transfer of ownership is required. (supplied by Dave Abrahams)"
But there already is a way to escape the scope, via swap().
Would it make more sense to just provide release() and have users specify const if they want? (const scoped_ptr/scoped_array would effectively disallow swapping/releasing.)
participants (11)
-
Alexader
-
Alexander
-
anony
-
Christopher Jefferson
-
Howard Hinnant
-
Matthieu Brucher
-
Nat Goodspeed
-
Richard Hadsell
-
Steven Watanabe
-
Thorsten Ottosen
-
Yang Zhang