P4003R0 — Coroutines for I/O
(7 items)
LEWG
This paper proposes the IoAwaitable protocol, a coroutine-native execution model for asynchronous I/O built directly on C++20 language features. The protocol consists of two concepts (IoAwaitable and IoRunnable), a type-erased executor (executor_ref), and thread-local frame allocator propagation, derived from a complete working networking library implementing timers, sockets, DNS, TLS, and HTTP. The design propagates executor, stop token, and frame allocator through coroutine chains without polluting function signatures, enabling ergonomic, high-performance I/O with compile-time protocol verification.
- Section 5.5, page 31 — std::pmr::get_default_resource() is described as "a process-wide thread-local allocator channel"; "process-wide" and "thread-local" are contradictory. Per [mem.res.global], get_default_resource() returns a process-wide (global) pointer, not a thread-local one. [1]
- Appendix A.1, page 60 — Claims "300 billion instructions" during a 100ms round-trip given billions-per-second execution rate; 0.1s x 3x10^9 = 3x10^8 = 300 million, not 300 billion — off by a factor of 1000. [1] [2]
-
Appendix A.4, page 62 — task<> used as a return type but task is declared template
with no default argument; task<> is ill-formed. Either provide a default (template ) or write task as in every other example in the paper. [2] [3] -
Section 3.5, page 16 — Code synopsis omits the run overload without an executor parameter, despite Section 3.4 prose and Section 10.1 wording both defining template
unspecified run(Args&&... args). [4] - Page 1, metadata and Revision History — Document date is 2026-02-22 (February) but revision history says "R0: March 2026 (pre-Croydon mailing)"; these contradict each other. [5]
References — Anthropic Citations API
[1]
"Date: 2026-02-22" / "R0: March 2026 (pre-Croydon mailing)"
"Date: 2026-02-22" / "R0: March 2026 (pre-Croydon mailing)"
[2]
"During a 100ms network round-trip, a modern CPU could have executed 300 billion instructions. "
"During a 100ms network round-trip, a modern CPU could have executed 300 billion instructions. "
[3]
"The standard library already accepted this tradeoff: std::pmr::get_default_resource() is a process-wide thread-local allocator channel, adopted in C++17."
"The standard library already accepted this tradeoff: std::pmr::get_default_resource() is a process-wide thread-local allocator channel, adopted in C++17."
[4]
"// Callback-based async (traditional style) socket.async_read(buffer, [](error_code ec, size_t n) { if (!ec) { // Process data, then start another read... socket.async_read(buffer,..."
"// Callback-based async (traditional style) socket.async_read(buffer, [](error_code ec, size_t n) { if (!ec) { // Process data, then start another read... socket.async_read(buffer,..."
[5]
"template< Executor Ex, class... Args > unspecified run( Ex ex, Args&&... args );"
"template< Executor Ex, class... Args > unspecified run( Ex ex, Args&&... args );"
Summary: P4003R0 proposes a coroutine-based framework for asynchronous I/O in the C++ standard library, built around a task coroutine type, an executor model, and primitives for structured concurrency including spawn, run, and channel. The design targets network programming and aims to replace callback-based async patterns with coroutine equivalents.
Pipeline: Discovery (Anthropic Opus + Citations API) → Verification Gate (OpenRouter Opus) → Report Writer (OpenRouter Opus)
Provenance: All references are machine-verified character positions from the Anthropic Citations API — deterministic, exact substrings, not model-generated quotes.
Provenance: All references are machine-verified character positions from the Anthropic Citations API — deterministic, exact substrings, not model-generated quotes.