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 operator is a unary operator introduced in C++20 that suspends the execution of a coroutine, yields control back to its caller or resumer, and defines the resumption point once the awaited operation completes. It acts as the primary state-machine transition mechanism within the C++ coroutine architecture.
Language Restrictions
Theco_await operator is subject to strict language restrictions. It cannot be used in the following contexts:
- The
mainfunction (which cannot be a coroutine). - Default arguments.
- Constructors or destructors.
- Catch blocks of a function-try-block.
- The initializer of a block-scope variable with
staticorthread_localstorage duration. - Functions declared as
constexprorconsteval. - Plain functions (the presence of
co_awaitis what transforms a function into a coroutine).
The Awaitable to Awaiter Transformation
When the compiler encountersco_await expression, it does not execute a simple function call. Instead, it resolves the Awaitable (expression) into an Awaiter object, which dictates the exact suspension and resumption behavior. The resolution follows a strict pipeline:
- Promise Transformation: The compiler checks the current coroutine’s promise type for the
await_transformmember. If the promise type declares anyawait_transformmember, name lookup succeeds, and the compiler exclusively attempts to use it. The result ofpromise.await_transform(expression)becomes the new awaitable. If no overload matches the specific expression, it results in a hard compile error; it does not fall back to the original expression. The original expression is used directly only ifawait_transformis not declared at all in the promise type. - Operator Overload: The compiler then searches for
operator co_awaitapplied to the awaitable from step 1. This follows standard C++ operator overloading rules. The compiler considers both memberoperator co_awaitfunctions and non-memberoperator co_awaitfunctions (found via Argument-Dependent Lookup) simultaneously. Standard overload resolution selects the best match. If an operator is found and successfully applied, its return value becomes the Awaiter. - Fallback: If no
operator co_awaitis found, the awaitable resulting from step 1 is treated directly as the Awaiter.
The Awaiter Interface
Once the Awaiter object is resolved, the compiler expects it to implement three specific methods:await_ready, await_suspend, and await_resume. The evaluation of co_await is mechanically expanded into the following pseudo-code, demonstrating how control flow depends on the return type of await_suspend:
Mechanics of await_suspend
The most critical phase of the co_await evaluation occurs during await_suspend. The return type of this method dictates the immediate control flow after the coroutine’s state has been saved:
void: The coroutine remains suspended, and control is unconditionally returned to the current caller or resumer.bool: If it returnstrue, control is returned to the caller. If it returnsfalse, the suspension is aborted, and the current coroutine is immediately resumed. Because the coroutine is already suspended whenawait_suspendis called (its state has been saved to the heap frame), returningfalseis typically used for operations that complete concurrently during the suspension process (e.g., a failed compare-and-swap), requiring the suspension to be aborted and the coroutine to continue execution.std::coroutine_handle<Z>: The current coroutine remains suspended, and execution is symmetrically transferred to the returned coroutine handle. This enables efficient tail-calls between coroutines without consuming additional stack frames.
Exception Handling Mechanics
Theco_await expansion guarantees precise exception propagation depending on which part of the Awaiter interface throws:
- If
await_readythrows: The exception propagates immediately into the surrounding coroutine body. The coroutine is never suspended. - If
await_suspendthrows: The coroutine’s suspension is aborted, the coroutine is immediately resumed (state restored), and the exception is propagated out of theco_awaitexpression. This guarantees that the coroutine state machine does not leak a suspended state if the suspension logic fails. - If
await_resumethrows: The exception propagates normally into the surrounding coroutine body. This occurs either after the coroutine has been successfully resumed, or immediately ifawait_readyreturnedtrueand bypassed suspension.
Standard Trivial Awaiters
The<coroutine> header provides two fundamental, empty awaiter types used to control basic suspension mechanics, often utilized within promise types:
Master C++ with Deep Grasping Methodology!Learn More





