This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Possible bug in shared_ptr(unique_ptr) constructor?
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: Brad Spencer <spencer at starscale dot com>
- Cc: "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Date: Mon, 7 Oct 2013 23:07:20 +0100
- Subject: Re: Possible bug in shared_ptr(unique_ptr) constructor?
- Authentication-results: sourceware.org; auth=none
- References: <20131007123915 dot GA11628 at starscale dot com> <CAH6eHdQFFO8EXFNavumHguHs5-wtDaDtJ=0kvY7E_WNHqydTrw at mail dot gmail dot com> <CAH6eHdRb-4nL-z7LZdLBwyjJHYY74NTCXDYJhcBaHeZLXzvC0g at mail dot gmail dot com> <20131007213416 dot GA6756 at starscale dot com>
On 7 October 2013 22:34, Brad Spencer wrote:
>
> Sorry for the delay. Bug 58659 filed and you CCed.
Got it - thanks!
>> And here's a suggested patch to fix it:
>
> I hacked in the patch to my installed toolchain headers and both my
> minimal test case and real program worked as expected. I'll do a full
> toolchain rebuild now with the patch. Thanks!
Great, thanks for testing it.
> BTW, I noticed that when it's created from unique_ptr, shared_ptr uses
> _Sp_counted_deleter even in the cases where the deleter is the
> std::default_delete<T>. Since _M_del is just a normal member of
> _Sp_counted_deleter (no empty base optimization, etc.), does this mean
> that a shared_ptr made from a unique_ptr uses a slightly larger than
> necessary count object? Is it worth trying to use _Sp_counted_ptr in
> that case?
It would be a nice space optimization and I was about to start coding
it up, but I remembered two points:
1) Users are allowed to specialize std::default_delete<T> if T depends
on a user-defined type (e.g.
default_delete<std::vector<SomeNonStdType>>) in which case it could do
something sneaky like log to std::cout every time it is invoked, so we
can't unconditionally remove any use of std::default_delete.
2) on the trunk (what will be GCC 4.9) both the allocator and the
deleter use the empty base optimization, so constructing a
shared_ptr<T> from a unique_ptr<T, default_delete<T>> should already
be no larger than necessary.
Valgrind shows me that this allocates 32 bytes with GCC 4.8 and 24
bytes with trunk:
std::shared_ptr<int>(std::unique_ptr<int>());
> (I feel greedy for even asking.)
Not at all, it was a good idea.
Thanks again for the report and the suggestion.