Created on 2024-09-19.00:00:00 last changed 1 month ago
Proposed resolution:
This wording is relative to N4988.
Modify [futures.promise] as indicated:
promise& operator=(promise&& rhs) noexcept;-9- Effects:
Abandons any shared state ([futures.state]) and then as ifEquivalent to `promise(std::move(rhs)).swap(*this)`.-10- Returns: `*this`.
Modify [futures.task.members] as indicated:
packaged_task& operator=(packaged_task&& rhs) noexcept;-11- Effects:
(11.1) — Releases any shared state ([futures.state]);(11.2) — callsEquivalent to `packaged_task(std::move(rhs)).swap(*this)`.-?- Returns: `*this`.
[ 2024-10-02; LWG telecon ]
Agreed to change `promise` the same way, which is safe for self-assignment and matches what all three of libstdc++, libc++ and MSVC do today. Ask SG1 to review.
[ 2024-10-02; Jonathan provides improved wording ]
Following reflector discussion, remove the "Releases any shared state" text completely. The remaining effects imply that the state will be abandoned anyway. This makes it safe against self-assignment.
[ 2024-10-02; Reflector poll ]
Set priority to 3 after reflector poll.
This wording is relative to N4988.
Modify [futures.task.members] as indicated:
packaged_task& operator=(packaged_task&& rhs) noexcept;-11- Effects:
- (11.1) —
ReleasesAbandons any shared state ([futures.state]);- (11.2) — calls `packaged_task(std::move(rhs)).swap(*this)`.
-?- Returns: `*this`.
The `packaged_task` move assignment operator is specified to release the previous shared state. This means it releases ownership, but does not make the shared state ready. Any future that shares ownership of the shared state will never receive a result, because the provider is gone. This means that any thread that waits on the future will block forever.
There is a note on `packaged_task::reset()` which claims that assignment abandons the state, which is not supported by any normative wording:
void reset();-26- Effects: As if `*this = packaged_task(std::move(f))`, where `f` is the task stored in `*this`.
[Note 2: This constructs a new shared state for `*this`. The old state is abandoned ([futures.state]). — end note]
Presumably, the intended behaviour of assignment was to abandon the shared state, i.e. make it ready with a `broken_promise` error, and then release it. That is what the `std::promise` move assignment does (see [futures.promise] p9). Both libstdc++ and libc++ abandon the state, despite what the standard says.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-10-02 16:29:29 | admin | set | messages: + msg14410 |
2024-10-02 11:50:49 | admin | set | messages: + msg14399 |
2024-10-02 11:50:49 | admin | set | messages: + msg14398 |
2024-09-20 12:26:44 | admin | set | messages: + msg14391 |
2024-09-19 00:00:00 | admin | create |