From 227831265043572707
X-Google-Thread: f78e5,52dd3e1082ac085e
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news1.google.com!news2.google.com!news4.google.com!news.glorb.com!newsgate.cistron.nl!newsfeed.stueberl.de!newsfeed.vmunix.org!peer-uk.news.demon.net!kibo.news.demon.net!news.demon.co.uk!demon!stump.algebra.com!devnull
From: hinnant@metrowerks.com (Howard Hinnant)
Newsgroups: comp.std.c++
Subject: Re: unique_ptr
Date: Sun,  4 Sep 2005 20:33:50 GMT
Organization: Metrowerks
Lines: 106
Sender: mail2news@demon.net
Approved: fjh@cs.mu.oz.au (Fergus Henderson , moderator of comp.std.c++)
Message-ID: <hinnant-E0A574.13161304092005@syrcnyrdrs-01-ge0.nyroc.rr.com>
References: <1125603471.570361.32720@o13g2000cwo.googlegroups.com> <hinnant-8804B5.11081102092005@syrcnyrdrs-03-ge0.nyroc.rr.com> <1125782448.174120.58820@g14g2000cwa.googlegroups.com>
NNTP-Posting-Host: news.news.demon.net
X-Trace: news.demon.co.uk 1125867439 19606 158.152.254.254 (4 Sep 2005 20:57:19 GMT)
X-Complaints-To: abuse@demon.net
NNTP-Posting-Date: Sun, 4 Sep 2005 20:57:19 +0000 (UTC)
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-User-Agent: MT-NewsWatcher/3.4 (PPC Mac OS X)
X-Greylisting: NO DELAY (Relay+Sender autoqualified);
	processed by UCSD_GL-v2.1 on mailbox7.ucsd.edu;
	Sun, 04 September 2005 10:16:24 -0700 (PDT)
X-Virus-Scanned: amavisd-new at cs.mu.OZ.AU
X-Received: (from fjh@localhost)
	by mulga.cs.mu.OZ.AU (8.12.10+Sun/8.12.9/Submit) id j84KXo8Q003389;
	Mon, 5 Sep 2005 06:33:50 +1000 (EST)
X-Path: comp-std-cpp-robomod!not-for-mail
X-NNTP-Posting-Date: Sun, 04 Sep 2005 13:16:14 EDT
X-Delivered-To: std-c++@ucar.edu
X-Spamscanner: mailbox7.ucsd.edu  (v1.6 Aug  4 2005 15:27:38, 0.0/5.0 3.0.4)
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Newsgroups: comp.std.c++
X-MailScanner: PASSED (v1.2.8 53812 j84HGNYg061277 mailbox7.ucsd.edu)
Xref: g2news1.google.com comp.std.c++:2013

In article <1125782448.174120.58820@g14g2000cwa.googlegroups.com>,
 "Jonas Persson" <l.j.persson@gmail.com> wrote:

> I dont think it would sprinkle the code with move.
> The only(?) places where you assign it lvaues is from a local variable:
> 
>   int* i = new int:
>   unique_ptr<int> ip(move(i));
> 
> which is never necessary and not to be recomended, and from prameters:
> 
> void foo(int *i) {
>   unique_ptr<int> ip(move(i));
> }
> 
> in which case the function resumes ownership of a pointer parameter.
> That should never happen except for smart pointer ctors.

<nit> There are non-smart-pointer classes that may take ownership of 
pointers (e.g. strstream).  But even so, your point is well taken.

> The correct
> signature of such a function should be: void foo(unique_ptr<int> i).
> 
> The major reason for unsafe code is memory owned by a naked pointer.
> Making passing lvalues less convenient than rvalues makes using naked
> pointers less convenient.
> 
> In your example, it is not nesessary to use move after the first one
> anyway. Probably get() is a better choise:
> 
>     template<class T>
> template<class Y, class D>
> shared_ptr<T>::shared_ptr(Y* p, D&& d)
>     : ptr_(p)
> {
>     Metrowerks::move_ptr<Y, D&> hold(move(p), d);
>     s_ = new detail::shared_ptr_deleter<Y, D>(hold.get(), d);
>     hold.release();
>     ...
> }
> 
> that way it is clear for the reader that you are giving the deleter a
> pointer already owned by hold. p should not be used after the first
> line regardless of move or no move.

You make some good points.  While reading your post, and re-reading your 
first post, a few more things have occurred to me:

1.  What if the unique_ptr<T>(T* ...) constructors looked as you suggest:

> explicit unique_ptr(T*&& p);

AND, said constructors zero'd p?  I.e.:

void foo(T* p)
{
    std::unique_ptr<T> up(std::move(p));
    assert(p == 0);
}

This would actually put teeth into what it means to move from a built-in 
pointer type.  The ownership of the memory really is transferred away 
from the built-in pointer.

2.  If thought 1 (zeroing the input pointer) is reasonable, does it 
still make sense to restrict the input parameter to an rvalue.  The 
constructors are already marked explicit, so the transfer of memory 
ownership is never implicit.  Do we need both the words "unique_ptr" and 
"move" in the statement to call this fact out, or is "unique_ptr" itself 
enough?

void foo(T* p)
{
    std::unique_ptr<T> up(p);  // sufficiently explicit?
    assert(p == 0);
    std::unique_ptr<T> up2(p);  // up2 is null
}

3.  This issue isn't specific to unique_ptr.  For any smart pointer for 
which the following would be bad:

T* p = ...
smart_pointer<T> p1(p);
smart_pointer<T> p2(p);

this same issues exists.  This includes shared_ptr and most any other 
smart pointer I can come up with.  This gives us vastly more experience 
to guide us.  For example it is an interesting exercise to go through 
the excellent "shared_ptr techniques" page to see how these proposed 
changes might effect these examples:

http://www.boost.org/libs/smart_ptr/sp_techniques.html

Would we be willing to have all standard smart pointers behave in the 
same way with respect to how they accept raw pointers (be it rvalue 
only, zeroing, whatever)?

-Howard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]



