Title
"Throws:" clauses of async and packaged_task are unimplementable
Status
c++17
Section
[futures.async][futures.task.members]
Submitter
Billy Robert O'Neal III

Created on 2016-07-07.00:00:00 last changed 90 months ago

Messages

Date: 2016-08-04.03:06:12

Proposed resolution:

This wording is relative to N4606.

  1. Change [futures.async] p6 to:

    Throws: system_error if policy == launch::async and the implementation is unable to start a new thread, or std::bad_alloc if memory for the internal data structures could not be allocated.

  2. Change [futures.task.members] p5 to:

    template <class F>
      packaged_task(F&& f);
    template <class F, class Allocator>
      packaged_task(allocator_arg_t, const Allocator& a, F&& f);
    

    Throws:

    1. (?) — Aany exceptions thrown by the copy or move constructor of f., or
    2. (?) — For the first version, std::bad_alloc if memory for the internal data structures could not be allocated.
    3. (?) — For the second version, any exceptions thrown by std::allocator_traits<Allocator>::template rebind_traits<unspecified>::allocate.
Date: 2016-08-04.03:06:12

[ 2016-08 Chicago ]

Wed PM: Move to Tentatively Ready

Date: 2016-08-03.02:08:33

[ 2016-07 Chicago ]

Alisdair thinks the third bullet is not quite right.

Previous resolution [SUPERSEDED]:

  1. Change [futures.async] p6 to:

    Throws: system_error if policy == launch::async and the implementation is unable to start a new thread, or std::bad_alloc if memory for the internal data structures could not be allocated.

  2. Change [futures.task.members] p5 to:

    template <class F>
      packaged_task(F&& f);
    template <class F, class Allocator>
      packaged_task(allocator_arg_t, const Allocator& a, F&& f);
    

    Throws:

    1. (?) — Aany exceptions thrown by the copy or move constructor of f., or
    2. (?) — For the first version, std::bad_alloc if memory for the internal data structures could not be allocated.
    3. (?) — For the second version, any exceptions thrown by std::allocator_traits<Allocator>::template rebind<unspecified>::allocate.
Date: 2016-07-07.00:00:00

std::async is a request from the user for type erasure; as any given function gets passed to async which returns only future<ReturnType>. Therefore, it needs to be able to allocate memory, as other issues (e.g. LWG 2202) indicate. However, async's Throws clause doesn't allow an implementation to do this, as it permits only future_error.

std::packaged_task's constructor allocates memory using a user supplied allocator. An implementation needs to call the user's allocate to allocate such memory. The user's allocate function is not constrained to throwing only bad_alloc; it can raise whatever it wants, but packaged_task's constructor prohibits this.

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2016-11-14 03:59:28adminsetstatus: pending -> wp
2016-11-14 03:55:22adminsetstatus: ready -> pending
2016-08-04 03:06:12adminsetmessages: + msg8390
2016-08-04 03:06:12adminsetstatus: new -> ready
2016-08-01 18:34:48adminsetmessages: + msg8289
2016-07-27 19:45:45adminsetmessages: + msg8260
2016-07-07 00:00:00admincreate