Date: Sat, 30 Apr 2022 10:34:24 -0400
Giuseppe wrote:
> (From a syntax point of view, I'm not sure how that is desirable, as one could no longer something like `other = reloc obj; delete &obj;`, but I don't think it's a particularly compelling use case...)
I would argue that the example given *is* a compelling use case for reloc. Remembering to delete objects (esp. at the right time) is a recipe for disaster.
Anyway, for what it’s worth, I think this is a compelling paper and would like to help move it forward in a constructive way.
WL
> On Apr 29, 2022, at 10:18 PM, Giuseppe D'Angelo via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> Hi,
>
>> On 29/04/2022 18:08, Sébastien Bini via Std-Proposals wrote:
>> About the last point, here is a quick overview: consider a class that guarantees (unique) ownership over some resources (i.e. allocated in constructor or otherwise throws, and deallocates in destructor). Basic examples are a non-null pointer class or a socket wrapper class. In a pure class design perspective:
>> * those classes shouldn't be copied as they provide unique access to
>> the resource.
>> * they could be movable but that's not ideal. The move constructor may
>> leave them in a dirty state or else rely on complicated mechanisms
>> not to do so. The move constructor for such classes:
>> o either breaks the class guarantee. That is the case if the
>> resource is moved from one instance to the other, leaving the
>> original instance with an invalid resource. As stated this
>> breaks our class invariant, which is to always offer unique
>> access to some resource.
>> o either needlessly complicates class design to work around the
>> naive implementation described above. This may include
>> allocating new unique resources to the moved instance in the
>> move constructor, or to do it lazily at a later stage the next
>> time the moved instance is reused.
>> o may not be appropriate. What would you do with a moved-from
>> socket wrapper instance? You don't know whether it owns any
>> socket, and if it does, it will probably be on something you
>> don't want. Most of the time, C++ programmers just discard
>> moved-from instances anyway as they are unsure of what they contain.
>> * it is a legitimate need to be able to "move" them around.
>> * the relocation constructor fits this need: the classes can be
>> relocated to another location. As the relocated instance is
>> guaranteed never to be touched again, the relocation constructor can
>> leave the relocated instance in a dirty invalid state (which the
>> move constructor cannot).
>
> I'm probably missing something, but from what you say above and from the TempDir example on page 7, all of this sounds like existing move semantics with the additional enforcement that a moved-from object isn't ever touched again (not even reassigned / reset).
>
> (From a syntax point of view, I'm not sure how that is desirable, as one could no longer something like `other = reloc obj; delete &obj;`, but I don't think it's a particularly compelling use case...)
>
> Anyways, a justification for relocation over move semantics on page 3 says that "the move constructor performs extra operations to ensure that the moved-from object remains at a valid state." This is not universally true. It is true for the Standard Library (and makes certain std::list implementations of move operations expensive / noexcept(false)); that's just stdlib's stance. A class author can always state that a moved-from object of their class is only partially formed. In this last case, I am not sure the paper convincly justifies operator reloc over the status quo (which includes clang-tidy "use after move" checks and so on).
>
> My 2 c,
> --
> Giuseppe D'Angelo
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> (From a syntax point of view, I'm not sure how that is desirable, as one could no longer something like `other = reloc obj; delete &obj;`, but I don't think it's a particularly compelling use case...)
I would argue that the example given *is* a compelling use case for reloc. Remembering to delete objects (esp. at the right time) is a recipe for disaster.
Anyway, for what it’s worth, I think this is a compelling paper and would like to help move it forward in a constructive way.
WL
> On Apr 29, 2022, at 10:18 PM, Giuseppe D'Angelo via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> Hi,
>
>> On 29/04/2022 18:08, Sébastien Bini via Std-Proposals wrote:
>> About the last point, here is a quick overview: consider a class that guarantees (unique) ownership over some resources (i.e. allocated in constructor or otherwise throws, and deallocates in destructor). Basic examples are a non-null pointer class or a socket wrapper class. In a pure class design perspective:
>> * those classes shouldn't be copied as they provide unique access to
>> the resource.
>> * they could be movable but that's not ideal. The move constructor may
>> leave them in a dirty state or else rely on complicated mechanisms
>> not to do so. The move constructor for such classes:
>> o either breaks the class guarantee. That is the case if the
>> resource is moved from one instance to the other, leaving the
>> original instance with an invalid resource. As stated this
>> breaks our class invariant, which is to always offer unique
>> access to some resource.
>> o either needlessly complicates class design to work around the
>> naive implementation described above. This may include
>> allocating new unique resources to the moved instance in the
>> move constructor, or to do it lazily at a later stage the next
>> time the moved instance is reused.
>> o may not be appropriate. What would you do with a moved-from
>> socket wrapper instance? You don't know whether it owns any
>> socket, and if it does, it will probably be on something you
>> don't want. Most of the time, C++ programmers just discard
>> moved-from instances anyway as they are unsure of what they contain.
>> * it is a legitimate need to be able to "move" them around.
>> * the relocation constructor fits this need: the classes can be
>> relocated to another location. As the relocated instance is
>> guaranteed never to be touched again, the relocation constructor can
>> leave the relocated instance in a dirty invalid state (which the
>> move constructor cannot).
>
> I'm probably missing something, but from what you say above and from the TempDir example on page 7, all of this sounds like existing move semantics with the additional enforcement that a moved-from object isn't ever touched again (not even reassigned / reset).
>
> (From a syntax point of view, I'm not sure how that is desirable, as one could no longer something like `other = reloc obj; delete &obj;`, but I don't think it's a particularly compelling use case...)
>
> Anyways, a justification for relocation over move semantics on page 3 says that "the move constructor performs extra operations to ensure that the moved-from object remains at a valid state." This is not universally true. It is true for the Standard Library (and makes certain std::list implementations of move operations expensive / noexcept(false)); that's just stdlib's stance. A class author can always state that a moved-from object of their class is only partially formed. In this last case, I am not sure the paper convincly justifies operator reloc over the status quo (which includes clang-tidy "use after move" checks and so on).
>
> My 2 c,
> --
> Giuseppe D'Angelo
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2022-04-30 14:34:27