Date: Sun, 19 Jul 2020 02:48:55 +0000
On 7/18/2020 11:32 PM, Arthur O'Dwyer wrote:
> On Sat, Jul 18, 2020 at 5:11 PM Jefferson Carpenter via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> Ooh, `return t` — now you're really getting into my home turf! :D
> Just to absolutely drive home why "copy-construct" and "move-construct"
> need to be considered part of the same overload set, let's look at how GCC
> and Clang compile this sort of implicitly-moving code. This "Fowl / eleven"
> example comes straight from my paper P1155 More Implicit Move
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1155r3.html>. As
> of C++20, GCC's behavior is "correct" and Clang's behavior is "incorrect";
> but in C++17 the opposite was true, and similar examples can always be
> constructed just outside the bounds of what we've standardized so far.
> https://godbolt.org/z/4qafK3
> Notice that GCC dereferences the pointer before deleting it (that is, it
> calls the move-ctor which "correctly" transfers ownership from ptr<int> to
> Fowl), and Clang deletes the pointer before dereferencing it (that is, it
> calls the copy-ctor which does not transfer ownership from ptr<int> to
> Fowl).
> This is the kind of pitfall that I do not want in a library facility.
>
> [...]
Interesting, so this would definitely depend on the implicit move
proposal and require that implicit move remain as it is. I would have
to agree that "spooky action at a distance" (changing the implicit move
to a copy breaking ptr<T>'s behavior) would be very bad. It sort of
depends on whether implicit move is enough self-evidently the correct
way to do it for it to be unlikely to be changed.
You know what I love about your proposal? It deletes words.
>
> Let's be very clear that what you have today *is **not refcounted*. A
> "reference count" is a count associated with the *controlled object*, not
> with the pointer(s) pointing to it. Two different pointers pointing to the
> same object should never disagree about the refcount on that object.
> You can do internal refcounting (like P0468
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0468r1.html>'s
> proposed `retain_ptr`) or external, "control-block"-based refcounting (like
> `std::shared_ptr` and `boost::local_shared_ptr`), but you can't hold a
> refcount inside the pointer object itself. That's not a refcount, because
> it can't be made to go up when someone else takes a reference, nor go down
> when someone else releases a reference.
> If you do want a non-thread-safe shared_ptr, `local_shared_ptr` is in Boost
> (and has already been rejected for standardization).
Right, it would have to contain a size_t* as the refcount, not just a
size_t. If local_shared_ptr was rejected it seems likely this would get
rejected as well, unless enough has changed since the local_shared_ptr
proposal for this one to be worth considering. There are two distinct
proposals, one with a non-thread-safe refcount, and one with a bool.
(Again the bool proposal requires functions called with a ptr argument
not to cause the ptr to be dereferenced after the function returns -- or
have explicit preconditions).
> On Sat, Jul 18, 2020 at 5:11 PM Jefferson Carpenter via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
> Ooh, `return t` — now you're really getting into my home turf! :D
> Just to absolutely drive home why "copy-construct" and "move-construct"
> need to be considered part of the same overload set, let's look at how GCC
> and Clang compile this sort of implicitly-moving code. This "Fowl / eleven"
> example comes straight from my paper P1155 More Implicit Move
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1155r3.html>. As
> of C++20, GCC's behavior is "correct" and Clang's behavior is "incorrect";
> but in C++17 the opposite was true, and similar examples can always be
> constructed just outside the bounds of what we've standardized so far.
> https://godbolt.org/z/4qafK3
> Notice that GCC dereferences the pointer before deleting it (that is, it
> calls the move-ctor which "correctly" transfers ownership from ptr<int> to
> Fowl), and Clang deletes the pointer before dereferencing it (that is, it
> calls the copy-ctor which does not transfer ownership from ptr<int> to
> Fowl).
> This is the kind of pitfall that I do not want in a library facility.
>
> [...]
Interesting, so this would definitely depend on the implicit move
proposal and require that implicit move remain as it is. I would have
to agree that "spooky action at a distance" (changing the implicit move
to a copy breaking ptr<T>'s behavior) would be very bad. It sort of
depends on whether implicit move is enough self-evidently the correct
way to do it for it to be unlikely to be changed.
You know what I love about your proposal? It deletes words.
>
> Let's be very clear that what you have today *is **not refcounted*. A
> "reference count" is a count associated with the *controlled object*, not
> with the pointer(s) pointing to it. Two different pointers pointing to the
> same object should never disagree about the refcount on that object.
> You can do internal refcounting (like P0468
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0468r1.html>'s
> proposed `retain_ptr`) or external, "control-block"-based refcounting (like
> `std::shared_ptr` and `boost::local_shared_ptr`), but you can't hold a
> refcount inside the pointer object itself. That's not a refcount, because
> it can't be made to go up when someone else takes a reference, nor go down
> when someone else releases a reference.
> If you do want a non-thread-safe shared_ptr, `local_shared_ptr` is in Boost
> (and has already been rejected for standardization).
Right, it would have to contain a size_t* as the refcount, not just a
size_t. If local_shared_ptr was rejected it seems likely this would get
rejected as well, unless enough has changed since the local_shared_ptr
proposal for this one to be worth considering. There are two distinct
proposals, one with a non-thread-safe refcount, and one with a bool.
(Again the bool proposal requires functions called with a ptr argument
not to cause the ptr to be dereferenced after the function returns -- or
have explicit preconditions).
Received on 2020-07-18 21:52:15