Title
Self-move-assignment of std::future and std::shared_future have unimplementable postconditions
Status
c++23
Section
[futures.unique.future][futures.shared.future]
Submitter
Jiang An

Created on 2022-10-19.00:00:00 last changed 5 months ago

Messages

Date: 2022-11-17.00:42:33

Proposed resolution:

This wording is relative to N4917.

  1. Modify [futures.unique.future] as indicated:

    future& operator=(future&& rhs) noexcept;
    

    -11- Effects: If addressof(rhs) == this is true, there are no effects. Otherwise:

    1. (11.1) — Releases any shared state ([futures.state]).
    2. (11.2) — move assigns the contents of rhs to *this.

    -12- Postconditions:

    1. (12.1) — valid() returns the same value as rhs.valid() prior to the assignment.
    2. (12.2) — If addressof(rhs) == this is false, rhs.valid() == false.

  2. Modify [futures.shared.future] as indicated:

    shared_future& operator=(shared_future&& rhs) noexcept;
    

    -13- Effects: If addressof(rhs) == this is true, there are no effects. Otherwise:

    1. (13.1) — Releases any shared state ([futures.state]).
    2. (13.2) — move assigns the contents of rhs to *this.

    -14- Postconditions:

    1. (14.1) — valid() returns the same value as rhs.valid() returned prior to the assignment.
    2. (14.2) — If addressof(rhs) == this is false, rhs.valid() == false.

    shared_future& operator=(const shared_future& rhs) noexcept;
    

    -15- Effects: If addressof(rhs) == this is true, there are no effects. Otherwise:

    1. (15.1) — Releases any shared state ([futures.state]).
    2. (15.2) — assigns the contents of rhs to *this.

      [Note 3: As a result, *this refers to the same shared state as rhs (if any). — end note]

    -16- Postconditions: valid() == rhs.valid().

Date: 2022-11-12.00:00:00

[ 2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP. ]

Date: 2022-11-15.00:00:00

[ 2022-11-07; Reflector poll ]

Set status to Tentatively Ready after six votes in favour during reflector poll.

Date: 2022-11-15.00:00:00

[ 2022-11-01; Jonathan provides wording ]

Date: 2022-11-15.00:00:00

[ 2022-11-01; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2022-10-19.00:00:00

The move assignment operators of std::future and std::shared_future have their postconditions specified as below:

Postconditions:

  • valid() returns the same value as rhs.valid() returned prior to the assignment.

  • rhs.valid() == false.

It can be found that when *this and rhs is the same object and this->valid() is true before the assignment, the postconditions can't be achieved.

Mainstream implementations (libc++, libstdc++, msvc stl) currently implement such self-move-assignment as no-op, which doesn't meet the requirements in the Effects: element. As discussed in LWG 3788, I think we should say self-move-assignment has no effects for these types.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2022-11-17 00:42:33adminsetmessages: + msg13083
2022-11-17 00:42:33adminsetstatus: voting -> wp
2022-11-08 03:46:49adminsetstatus: ready -> voting
2022-11-07 17:36:29adminsetmessages: + msg12948
2022-11-07 17:36:29adminsetstatus: new -> ready
2022-11-01 17:31:55adminsetmessages: + msg12909
2022-11-01 17:31:55adminsetmessages: + msg12908
2022-11-01 17:30:19adminsetmessages: + msg12907
2022-10-19 00:00:00admincreate