Created on 2025-08-27.00:00:00 last changed 2 weeks ago
Proposed resolution:
This wording is relative to N5014.
Modify [exec.connect] as indicated:
[Drafting note: This should cover the design intent, although we may want to spell this out more explicitly in terms of the exact semantics in a similar way to [coro.generator.promise] p17, which lists overloads of operator `new()` and describes the rebound allocator type which allocates storage in chunks of size `__STDCPP_DEFAULT_NEW_ALIGNMENT__`.]
-5- Let `V` name the type await-result-type<DS, connect-awaitable-promise>, let `Sigs` name the type
[…]and let connect-awaitable be an exposition-only coroutine defined as follows:
namespace std::execution { […] }Any dynamically allocated storage required for the coroutine state allocated by an invocation of the form connect-awaitable(sndr, rcvr) is allocated using the allocator obtained from `get_allocator(get_env(rcvr))`.
-6- […]
[ 2026-05-15; LWG telecon. Status: New → Open. ]
SG1 discussed this in November and responded:
Poll: SG1 recommends to specify that the destruction and the deallocation of coroutine state happens before emitting senders/receivers completion signal for LWG4356. Outcome: Strong consensus in favor.
LWG discussion decided that the wording needs to say something like
"using the allocator obtained from `get_allocator(get_env(rcvr))` if that
expression is well-formed, and from allocator<byte>()
otherwise." The ordering problem identified by SG1 wouldn't be a problem if
it always used `std::allocator`, but obtaining an allocator from the
environment introduces the potential lifetime issue. Since everything in
[exec.connect] is specified in code, that code should be updated
to include obtaining and using an allocator for the coroutine frame,
and destroying and deallocating everything before the completion signal.
This needs a lot of work.
[ 2025-10-23; Reflector poll. ]
Set priority to 2 after reflector poll.
"The `get_allocator` query doesn't have a default and I think that isn't covered in the proposed resolution."
The wording for `connect()` ([exec.connect]) handles passing awaitable types as the sender argument by calling the connect-awaitable() coroutine and having it execute a `co_await` expression.
The connect-awaitable() coroutine will typically need to dynamically allocate storage for the coroutine state and, as specified, this currently just always uses the global default allocator. This is because the connect-awaitable-promise type does not define any member operator `new/delete` overloads. It seems desirable for this facility to use the allocator obtained from the receiver, by calling `get_allocator(get_env(rcvr))`, in order to allocate storage for the coroutine-state instead of always using global operator `new`. This would give the user at least some level of control over how this allocation is performed.| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2026-05-19 21:02:09 | admin | set | status: new -> open |
| 2026-05-19 21:00:40 | admin | set | messages: + msg16300 |
| 2025-10-23 12:39:14 | admin | set | messages: + msg15400 |
| 2025-09-14 11:09:35 | admin | set | messages: + msg15028 |
| 2025-08-27 00:00:00 | admin | create | |