Document Number: P0912R5
Date: 2019-02-22
Audience: WG21
Revises: P0912R4
Reply to:

Merge Coroutines TS into C++20 working draft


This paper proposes merging Working Draft of Coroutines TS [N4775] into the C++20 working draft [N4800].

Revision history

r0: initial revision







Coroutines address the dire need by dramatically simplifying development of asynchronous code. Coroutines have been available and in use for 5 years. We have shipping implementations from two major compiler vendors. It is time to merge Coroutines TS to the working paper.


Rationale: Required for new features. The requires keyword is added to introduce constraints through a requires-clause or a requires-expression. The concept keyword is added to enable the definition of concepts (12.6.8). The co_await, co_yield, and co_return keywords are added to enable the definition of coroutines (\ref{dcl.fct.def.coroutine}). Effect on original feature: Valid ISO C++ 2017 code using concept, co_await, co_yield, co_return, or requires as an identifier is not valid in this International Standard.

Effect on original feature: The following C++ headers are new: <compare>, <coroutine>, and <syncstream>. Valid C++ 2017 code that #includes headers with these names may be invalid in this International Standard.

An await-expression shall appear only in a potentially-evaluated expression within the compound-statement of a function-body outside of a handler (Clause 18). In a declaration-statement or in the simple-declaration (if any) of a for-init-statement, an await-expressionawait-expression shall appear only in an initializer of that declaration-statement or simple-declaration. An await-expression shall not appear in the initializer of a block-scope variable with static or thread storage duration.

12. If the evaluation of the expression p.unhandled_exception() exits via an exception, the coroutine is considered suspended at the final suspend point.

13. The expression co_await p.final_suspend() shall not be potentially-throwing ([except.spec]).

1. Resuming a coroutine via resume, operator(), or destroy on an execution agent other than the one it was suspended on has implementation-defined behavior unless each is either an instance of std::thread or the thread that executes main.

[Note: A coroutine that is resumed on a different execution agent should avoid relying on consistent thread identity throughout, such as holding a mutex object across a suspend point. — end note ]

[Note: A concurrent resumption of the coroutine may result in a data race. — end note ]

[ Note: A concurrent resumption of the coroutine via resume, operator(), or destroy may result in a data race. —end note ]