An awaitable in C++ is any type that can serve as the operand to theDocumentation Index
Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
Use this file to discover all available pages before exploring further.
co_await unary operator within a C++20 coroutine. It represents an expression whose evaluation dictates the exact mechanics of coroutine suspension, the logic executed immediately after the coroutine state is saved, and the value yielded upon coroutine resumption.
To understand the mechanics of co_await, it is necessary to distinguish between an Awaitable and an Awaiter:
- Awaitable: The original type or expression passed to
co_await. - Awaiter: The internal object that directly implements the suspension lifecycle methods (
await_ready,await_suspend, andawait_resume).
The co_await Resolution Process
When the compiler evaluates co_await expr, it must resolve the Awaitable (expr) into an Awaiter. This transformation follows a strict, sequential evaluation:
- Promise Transformation: The compiler first checks if the coroutine’s promise type declares a member named
await_transform. If the name is found, the compiler evaluatespromise.await_transform(expr). If the name is found but no overload matchesexpr, the program is ill-formed and results in a compile error. The fallback toexpronly occurs if the nameawait_transformis not found at all in the promise type. Let this intermediate result bea. - Operator Overload: The compiler then checks if
asupportsoperator co_await(either as a member function ofaor as an overloaded non-member function). If it does, the compiler evaluatesoperator co_await(a). If no such operator exists, the result remainsa. - Awaiter Validation: The final result of these transformations is the Awaiter object. The compiler verifies that this Awaiter type implements the three required lifecycle methods.
The Awaiter Interface
The compiler expects the resolved Awaiter object to expose the following interface:1. await_ready()
This method returns a type that is contextually convertible to bool. If it evaluates to true, the coroutine bypasses suspension entirely, avoiding the overhead of saving the instruction pointer and registers to the already-allocated coroutine frame, and immediately proceeds to await_resume(). If it evaluates to false, the coroutine state is saved, and execution proceeds to await_suspend().
2. await_suspend(std::coroutine_handle<>)
This method is invoked after the compiler has saved the coroutine’s local variables and instruction pointer into the coroutine frame. It receives a std::coroutine_handle pointing to the suspended coroutine. The return type of await_suspend dictates the next step in the control flow:
void: Control returns immediately to the current caller or resumer of the coroutine.bool: Iftrue, control returns to the caller. Iffalse, the coroutine is immediately resumed.std::coroutine_handle<OtherPromise>: The compiler performs symmetric control transfer, immediately resuming the returned coroutine handle without consuming additional stack space.
noexcept:
According to the C++ standard ([expr.await]), if await_suspend exits via an exception, the exception is safely caught, the coroutine is restored to its resumed state, and the exception is immediately re-thrown from the co_await expression.
Despite this safety mechanism, it is a strong best practice to mark await_suspend as noexcept. If await_suspend throws an exception after it has already scheduled the coroutine for resumption on another thread (or otherwise published the handle), the local exception handler will resume the coroutine while the concurrent thread also attempts to resume it. This results in a double-resume, which is Undefined Behavior (UB) and causes memory corruption.
3. await_resume()
This method is called immediately before the co_await expression completes, either after the coroutine is resumed from suspension, or directly after await_ready() if suspension was bypassed. The return type of this method becomes the evaluated result of the co_await expression.
Standard Trivial Awaiters
The<coroutine> header provides two fundamental, compiler-optimized awaiter types used to control basic suspension behavior:
Master C++ with Deep Grasping Methodology!Learn More





