Comparing Coroutines in C++ and Rust 1

Aspect C++ Coroutines Rust Coroutines (async/await)
Syntax & Usage Uses co_await, co_yield, co_return inside coroutine functions. Uses async fn and .await.
Return Type Coroutine functions can return various types, often requiring custom promise types and handle management. async fn returns an object implementing the Future trait.
State Management The coroutine’s state (including suspension points) is managed
by the compiler and runtime, often requiring explicit handle manipulation.
The state machine is generated by the compiler, and the runtime (like Tokio) schedules and polls these futures.
Scheduling No built-in scheduler;
coroutines are “fire-and-forget” unless explicitly managed.
The user or library must schedule and resume them.
Requires an async runtime (e.g., Tokio, async-std) to poll and schedule futures.
Memory Safety Relies on C++’s memory model;
can be error-prone with manual memory management.
Enforces strict memory safety via Rust’s ownership and borrowing rules.
Flexibility Supports both stackless (standard) and
stackful (via libraries) coroutines.
Only stackless coroutines are supported;
stackful coroutines are not part of Rust’s async model.
Underlying Model Awaitables continue the coroutine from the bottom up (the callee resumes the caller). The runtime polls the future from the top down (the executor drives progress).

Note

  • The Coroutines feature was officially added to C++20.

References

  1. sourced from Perplexity