Talk:cpp/memory/shared ptr/shared ptr
The page says:
"When constructing a shared_ptr from a raw pointer to an object of a type derived from std::enable_shared_from_this, the constructors of shared_ptr detect other owners of the object through the weak reference stored in that base class. This allows ownership of the object to be shared with existing shared_ptrs. Otherwise, it is undefined behavior to construct a shared_ptr for an object that is already managed by another shared_ptr."
But this does not work in GCC. Is it in the C++ standard? Which paragraph?
--78.12.76.238 11:14, 3 February 2014 (PST)
- This description follows §20.8.2.4[util.smartptr.enab]/11, which says "The shared_ptr constructors that create unique pointers can detect the presence of an enable_shared_from_this base and assign the newly created shared_ptr to its __weak_this member.". In LLVM libc++ this functionality is implemented by the call to __enable_weak_this from the shared_ptr's constructors. GNU libstdc++ makes a call to __enable_shared_from_this_helper from __shared_ptr's constructors. (note: this may have been worded poorly on this page, I'll review) --Cubbi (talk)
- Yes, the description on this page was wrong, fixed. Thank you for bringing it up! --Cubbi (talk) 12:01, 3 February 2014 (PST)
- Much better now. I made a small edit that makes wording even more explicit. I think that even a tiny misunderstanding of the role of std::enable_shared_from_this can bring to daunting bugs. Feel free to rollback my edit, though. --78.12.77.107 09:38, 4 February 2014 (PST)
The example on https://en.cppreference.com/w/cpp/memory/weak_ptr/owner_before shows a constructor in the form std::shared_ptr<int> xx(std::shared_ptr<Foo>)yy, &yy->n1) where n1 is an element of type int within Foo. Shouldn't constructor example (8) read: "template< class Y > shared_ptr( const shared_ptr<T>& r, Y* ptr ) noexcept" ? Fneske (talk) 10:34, 27 September 2020 (PDT)
- It's correct as is. In the expression std::shared_ptr<int>(p1, &p1->n1) where decltype(p1) is std::shared_ptr<Foo>,
Tis int,YisFoo, and decltype(&p1->n1) is int*, which is std::shared_ptr<int>::element_type* as required. --Ybab321 (talk) 02:30, 28 September 2020 (PDT)
[edit] aliasing c'tor with nullptr?
Can we clarify what happens if we pass `nullptr` as the second argument to the aliasing c'tor? It seems to Just Work, but in a very weird way: https://godbolt.org/z/sj6zP8 It puts things in a state where we have a `nullptr` that is keeping something alive. Is that guaranteed by the standard? BenFrantzDale (talk) 12:32, 10 December 2020 (PST)
- It's valid. The shared_ptr instance is what's keeping something alive, though, not the nullptr that happens to sit in its other member. I suppose we could mention it, though it's two levels of obscurity down (level one being the existence of aliasing ctor itself and its intended use). I found one blog mentioning this (from "The other special case is where the stored object is NULL while the owned one is not.") --Cubbi (talk) 09:11, 11 December 2020 (PST)
[edit]
The page says: "In C++11 and C++14 it is valid to construct a std::shared_ptr<T> from a std::unique_ptr<T[]>:"
However, the code snippet does not compile with g++: https://ideone.com/s6AHOv
- seems it was applied as a defect, retroactively; you can get it to compile in gcc 6.2 and clang 3.2. And with modern clang, you can see it is checking that it's not an array even in C++11 mode: note "!is_array"
- ... but then it builds again with trunk clang in C++17 mode, worth a closer look at why. --Cubbi (talk) 11:25, 5 September 2021 (PDT)