This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2276. Missing requirement on `std::promise::set_exception`

Section: 32.9 [futures] Status: C++17 Submitter: Jonathan Wakely Opened: 2013-07-30 Last modified: 2017-07-30

Priority: Not Prioritized

View all other issues in [futures].

View all issues with C++17 status.

Discussion:

The standard does not specify the behaviour of this program:

>     #include <future>
>     #include <cassert>

>     struct NonTrivial
>     {
>       NonTrivial() : init(true) { }
>       ~NonTrivial() { assert(init); }
>       bool init;
>     };

>     int main()
>     {
>       std::promise<NonTrivial> p;
>       auto f = p.get_future();
>       p.set_exception(std::exception_ptr());
>       f.get();
>     }

The standard doesn't forbid making the state ready with a null `exception_ptr`, so what should `get()` return? There's no stored exception to throw, but it can't return a value because none was initialized.

A careful reading of the standard shows 32.9.5 [futures.state] p8 says "A shared state is ready only if it holds a value or an exception ready for retrieval." One can infer from the fact that `set_exception()` makes the state ready that it must store a value or exception, so cannot store "nothing", but that isn't explicit.

The `promise::set_exception()` and `promise::set_exception_at_thread_exit()` members should require `p != nullptr` or should state the type of exception thrown if `p` is null.

[2015-02 Cologne]

Handed over to SG1.

[2015-05 Lenexa, SG1 response]

SG1 provides P/R and requests move to SG1-OK status: Add Requires clauses for promise (30.6.5 [futures.promise]) set_exception (before p18) and set_exception_at_thread_exit (before p24): Requires: p is not null.

[2015-10, Kona issue prioritization]

Priority 0, move to Ready

Proposed resolution:

This wording is relative to N4431.

Add Requires clauses for promise (32.9.6 [futures.promise]) `set_exception` (before p18) and `set_exception_at_thread_exit` (before p24): Requires: `p` is not null.

1. Change 32.9.6 [futures.promise] as depicted:

   >     void set_exception(exception_ptr p);

   > > -??- Requires: `p` is not null.

   > > -18- Effects: atomically stores the exception pointer `p` in the shared state and makes that state ready (30.6.4).

   >     void set_exception_at_thread_exit(exception_ptr p);

   > > -??- Requires: `p` is not null.

   > > -24- Effects: Stores the exception pointer `p` in the shared state without making that state ready immediately. […]