C++ Logo

std-proposals

Advanced search

[std-proposals] Async Lambdas

From: Rhidian De Wit <rhidiandewit_at_[hidden]>
Date: Tue, 30 Sep 2025 19:20:54 +0200
Hi all,

A problem I regularly face at work is asynchronous lambdas, specifically
the fact that the closure of an asynchronous lambda does not necessarily
stay in scope after a suspension point, meaning that even if the captured
variables remain in-scope, the capture group itself goes out-of-scope,
causing all captured values in the lambda to become garbage.

This is of course mentioned in the C++ core guidelines:
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cp51-do-not-use-capturing-lambdas-that-are-coroutines

However, I find myself wondering: why?
Why does the capture group out-of-scope?
>From cppreference
<https://en.cppreference.com/w/cpp/language/coroutines.html>:

   - *the coroutine state, which is internal, dynamically-allocated storage
   (unless the allocation is optimized out), object that contains *


   - * the promise object *
   - * the parameters (all copied by value) *
   - * some representation of the current suspension point, so that a
   resume knows where to continue, and a destroy knows what local variables
   were in scope *
   - * local variables and temporaries whose lifetime spans the current
   suspension point. *

*When a coroutine begins execution, it performs the following: *

   - *allocates
   <https://en.cppreference.com/w/cpp/language/coroutines.html#Dynamic_allocation>
   the coroutine state object using operator new
   <https://en.cppreference.com/w/cpp/memory/new/operator_new.html>. *
   - * copies all function parameters to the coroutine state: by-value
   parameters are moved or copied, by-reference parameters remain references
   (thus, may become dangling, if the coroutine is resumed after the lifetime
   of referred object ends — see below for examples). *

Could the lambda capture group not be allocated on the heap alongside all
other heap allocated memory? This would make asynchronous lambdas possible
and safe-to-use, which would be great, instead of having to always rely on
actual functions.

The reason that this is a problem for us is because of backwards
compatability: We have a lot of old asynchronous code predating coroutines,
and during conversions to coroutines, such details are easily forgotten,
especially by people who aren't very used to coroutines and their quirks.

Is there any ongoing proposal to address this problem?

Thanks in advance for the replies and consideration,

-- 
Rhidian De Wit
Software Engineer - Barco

Received on 2025-09-30 17:21:11