This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
3582. Unclear wherestd::async
exceptions are handled
Section: 32.10.9 [futures.async] Status: New Submitter: Jonathan Wakely Opened: 2021-08-23 Last modified: 2021-09-30
Priority: 3
View other active issues in [futures.async].
View all other issues in [futures.async].
View all issues with New status.
Discussion:
32.10.9 [futures.async] (3.1) says:
Any exception propagated from the execution of
invoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
is stored as the exceptional result in the shared state.
It's not clear whether this includes the evaluation of the decay-copy
calls in the calling thread, or only the invocation of invoke with the results of those decay-copy
calls.
invoke
, not the calls to decay-copy
. Exceptions from the decay-copy
calls are propagated to the caller of std::async
. We should clarify that that's what the standard means.
[2021-09-20; Reflector poll]
Set priority to 3 after reflector poll.
[2021-09-20; Jonathan updates wording to change the Throws: and attempt to align the Effects: with the deferred function case. ]
Previous resolution [SUPERSEDED]:
This wording is relative to N4892.
Modify 32.10.9 [futures.async] as indicated:
template<class F, class... Args> [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(F&& f, Args&&... args); template<class F, class... Args> [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(launch policy, F&& f, Args&&... args);-2- Mandates: […]
-3- Effects: The first function behaves the same as a call to the second function with apolicy
argument oflaunch::async | launch::deferred
and the same arguments forF
andArgs
. The second function creates a shared state that is associated with the returnedfuture
object. The further behavior of the second function depends on thepolicy
argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):
(3.1) — If
launch::async
is set inpolicy
, callsinvoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
(22.10.4 [func.require], 32.4.3.3 [thread.thread.constr]) as if in a new thread of execution represented by athread
object with the calls todecay-copy
being evaluated in the thread that calledasync
. Any return value is stored as the result in the shared state. Any exception propagated from the execution ofinvoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
call toinvoke
is stored as the exceptional result in the shared state. [Note ?: Exceptions from thedecay-copy
calls are propagated to the caller. — end note] Thethread
object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.[…]
Proposed resolution:
This wording is relative to N4892.
Modify 32.10.9 [futures.async] as indicated:
template<class F, class... Args> [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(F&& f, Args&&... args); template<class F, class... Args> [[nodiscard]] future<invoke_result_t<decay_t<F>, decay_t<Args>...>> async(launch policy, F&& f, Args&&... args);-2- Mandates: […]
-3- Effects: The first function behaves the same as a call to the second function with apolicy
argument oflaunch::async | launch::deferred
and the same arguments forF
andArgs
. The second function creates a shared state that is associated with the returnedfuture
object. The further behavior of the second function depends on thepolicy
argument as follows (if more than one of these conditions applies, the implementation may choose any of the corresponding policies):
(3.1) — If
launch::async
is set inpolicy
, callsinvoke(decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args))...)
(22.10.4 [func.require], 32.4.3.3 [thread.thread.constr]) as if in a new thread of execution represented by athread
object with the calls todecay-copy
being evaluated in the thread that calledasync
. Any return value is stored as the result in the shared state. Any exception propagated from the execution ofinvoke( decay-copy(std::forward<F>(f)), decay-copy(std::forward<Args>(args)...) std::move(g), std::move(xyz))
is stored as the exceptional result in the shared state , whereg
is the result ofdecay-copy(std::forward<F>(f))
andxyz
is the result ofdecay-copy(std::forward<Args>(args))...
. [Note ?: Exceptions from thedecay-copy
calls are propagated to the caller. — end note] Thethread
object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.[…]
[…]
-6- Throws:
system_error
ifpolicy == launch::async
and the implementation is unable to start a new thread;std::bad_alloc
if memory for the internal data structures cannot be allocated ; or any exception thrown by the initialization of the objects returned by thedecay-copy
calls.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4