This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
future/shared_future unwrapping constructor when given an invalid futureSection: 99 [concurr.ts::futures.unique_future], 99 [concurr.ts::futures.shared_future] Status: C++23 Submitter: Tim Song Opened: 2016-04-22 Last modified: 2023-11-22
Priority: 2
View all issues with C++23 status.
Discussion:
Addresses: concurr.ts
In the concurrency TS, the future/shared_future unwrapping constructors
future(future<future<R>>&&) noexcept; shared_future(future<shared_future<R>>&& rhs) noexcept;
appear to implicitly require rhs be valid (e.g., by referring to its shared state, and by requiring a
valid() == true postcondition). However, they are also marked noexcept, suggesting that they
are wide-contract, and also makes the usual suggested handling for invalid futures, throwing a
future_error, impossible.
noexcept should be removed, or the behavior with an invalid future should be specified.
Original resolution alternative #1 [NOT CHOSEN]:
This wording is relative to N4577.
Strike the
noexcepton these constructors in 99 [concurr.ts::futures.unique_future]/1-2 and 99 [concurr.ts::futures.shared_future]/1-2, and optionally add a Requires:rhs.valid() == trueparagraph.
[2016-11-12, Issaquah]
Sat PM: We prefer alternative #2 - Move to review
[2018-06; Rapperswil, Wednesday evening session]
DR: there is a sentence ended followed by an entirely new sentence
JM: so the period should be a semicolon in both edits
MC: ACTION I can make the change editorially
ACTION move to Ready
[2018-11, Adopted in San Diego]
Proposed resolution:
This wording is relative to N4577.
Alternative #2: Specify that an empty (
shared_)futureobject is constructed ifrhsis invalid, and adjust the postcondition accordingly.
Edit 99 [concurr.ts::futures.unique_future] as indicated:
future(future<future<R>>&& rhs) noexcept;-3- Effects: If
rhs.valid() == false, constructs an emptyfutureobject that does not refer to a shared state. Otherwise, cConstructs afutureobject from the shared state referred to byrhs. T; thefuturebecomes ready when one of the following occurs:
Both the
rhsandrhs.get()are ready. The value or the exception fromrhs.get()is stored in thefuture's shared state.
rhsis ready butrhs.get()is invalid. An exception of typestd::future_error, with an error condition ofstd::future_errc::broken_promiseis stored in thefuture's shared state.-4- Postconditions:
valid() == truevalid()returns the same value asrhs.valid()prior to the constructor invocation..
rhs.valid() == false.
Edit 99 [concurr.ts::futures.shared_future] as indicated:
shared_future(future<shared_future<R>>&& rhs) noexcept;-3- Effects: If
rhs.valid() == false, constructs an emptyshared_futureobject that does not refer to a shared state. Otherwise, cConstructs ashared_futureobject from the shared state referred to byrhs. T; theshared_futurebecomes ready when one of the following occurs:
Both the
rhsandrhs.get()are ready. The value or the exception fromrhs.get()is stored in theshared_future's shared state.
rhsis ready butrhs.get()is invalid. Theshared_futurestores an exception of typestd::future_error, with an error condition ofstd::future_errc::broken_promise.-4- Postconditions:
valid() == truevalid()returns the same value asrhs.valid()prior to the constructor invocation..
rhs.valid() == false.