CppCon 2016: James McNellis “Introduction to C++ Coroutines"

CppCon · 52K views · 2016 · 58:03

Open on YouTube

C, C++, Rust, Go & systems languagesProgramming language designtalk

Why Stack Overflow recommends it

Stack Overflow users link it as the go-to explanation of how C++ coroutines work under the hood, especially promise types, awaitables and coroutine lifetime.

Recommended by 3 people across 3 different months, 2016 to 2022.

What it is

James McNellis of the Visual C++ team gives a CppCon 2016 introduction to C++ coroutines, then still the Coroutines TS. He explains the rationale, then builds up a series of coroutines to show promise types, awaitables, co_await/co_yield, and how existing libraries can be adapted.

What people said

Strong rec Cruz Jean · 2019-05 · Stack Overflow · on “What causes this code `Segmentation fault` after a coroutine call `promise_type::return_value()`?”

I think the lack of interest in this question is mostly because coroutines are so new (not even technically standardized at this point). This is an interesting topic though. I had to do some digging, but I found this talk from CppCon 2016 [this video] was immensely helpful, as well as this draft of the coroutine standard [LINK] . Getting right into the problem: I think you (and me too prior to doing some research) are a bit confused as to how coroutines are supposed to be written, which unfortunately requires a lot of understanding about how the C++ language implements them under the hood. For instance, coroutines must be controlled (including resumption) via a handle, but you weren't storing the

Strong rec Tom Huntington · 2022-07 · Stack Overflow · on “(IAsyncOperation for non WinRT types) Run coroutine task on Windows thread pool”

@IInspectable looking at the cppwinrt generated headers was the first thing I did, but I'll try again. McNellis gave an unusually lucid talk on co-routines [this video] so I'm not stuck, just cant find an easy solution

Recommends JohnB · 2016-11 · Stack Overflow · on “Is it possible to return many values from a loop in a function? C++”

With coroutines (working under Visual Studio 2015 Update 3) it would look like this: generator<float> MyFunc(float First, float Second) { while (First < Second) { First++; co_yield First; } } And then you could write for (auto && i : MyFunc(2,7)) { std::cout << i << "\n"; } There is a talk about this on Youtube: [this video] See here for exactly your example: [this video] If you do not want to wait for coroutines, have a look at the boost::range library. Or implement your own kind-of iterator struct counter { counter (int first, int last) : counter {first, last, first} {} counter begin () const { return counter {first, last, first}; } counter end () const { return counter {first, last, last}; } int op

Cites DuckQueen · 2016-10 · Stack Overflow · on “Is there any reason for "co_" wording in new C++ standard?”

Reasons for this syntax: no one at cppcon knows [this video] Reasons against it: It all worked perfectly with out co_ see here [LINK] and was expected (e.g. taught in universities) Complicated code (the more chars we type the more errors we get) Can be harder to understand and move from other languages (where return and await wording is used [LINK] ) So why we co_ wording is there while co_ less sintax was compiler supported in 2015?

Cites Zbyl · 2016-11 · Stack Overflow · on “Resuming final_suspend causes error, not destroys coroutine”

James McNellis in his presentation “Introduction to C++ Coroutines" ( [this video] ) says the following: A coroutine is destroyed when: final_suspend is resumed, coroutine_handle<>::destroy() is called, whichever happens first. In my tests I see (VS 2015, VS 2017 RC), that resuming coroutine that is suspended on final_suspend causes an error instead: Unhandled exception at 0x010B9EDD in Awaits2017.exe: RangeChecks instrumentation code detected an out of range array access. occurred Any ideas what might be going on here? #include <experimental/resumable> using namespace std; using namespace std::experimental; struct Coro { coroutine_handle<> m_coro; Coro(coroutine_handle<> coro) : m_coro(coro) {}

Cites y_gyan · 2017-09 · Stack Overflow · on “Non-void Coroutine Without Return Statement”

I am trying to wrap my head around the C++ coroutine feature. I read Kenny's article ( C++ - Introducing C++/WinRT [LINK] ) and also tried watching this presentation, CppCon 2016: James McNellis “Introduction to C++ Coroutines" [this video] . I keep seeing non-void "functions" without some form of return statement. As an example, see the following code sample from Kenny's article. The PrintFeedAsync function/coroutine has an IAsyncAction return type but there is no return statement in the definition. could someone explain how this works? IAsyncAction PrintFeedAsync() { Uri uri(L" [LINK] "); SyndicationClient client; SyndicationFeed feed = co_await client.RetrieveFeedAsync(uri); for (SyndicationIt

Cites Jonas Greitemann · 2019-03 · Stack Overflow · on “C++20 coroutines: implementing an awaitable future”

Since the Coroutines TS has been accepted into C++20 at the ISO meeting at Kona, I started playing around with them a bit for myself. Clang already has decent support for coroutines but the implementation of the library support is still lacking. In particular, the Awaitable types such as std::future , std::generator , etc. have not been implemented yet. Thus, I took it upon myself to make std::future awaitable. I largely followed the talk by James McNellis at CppCon 2016 [this video] , specifically this slide: [this video] This being 2019, I actually had some trouble with the (presumably untested?) code on this slide: It seems to me overloading operator co_await is not a thing anymore? Instead one sho

Cites David Ledger · 2019-07 · Stack Overflow · on “Are stackless C++20 coroutines a problem?”

Based on the following it looks like coroutines in C++20 will be stackless. [LINK] I'm concerned for many reasons: On embedded systems heap allocation is often not acceptable. When in low level code, nesting of co_await would be useful (I don't believe stackless co-routines allow this). With a stackless coroutine, only the top-level routine may be suspended. Any routine called by that top-level routine may not itself suspend. This prohibits providing suspend/resume operations in routines within a general-purpose library. [LINK] More verbose code because of the need for custom allocators and memory pooling. Slower if the task waits for the operating system to allocate it some memory (without

Cites Vladislav · 2020-06 · Stack Overflow · on “Coroutine usages for asynchronous programming in C++”

I decided to immerse into C++ coroutines, have read some articles and watched a lot of videos. It is said that coroutines are useful for asynchronous programming. As an example it is usual demonstrated similar examples. Let's look to one of them: James McNellis "Introduction to C++ Coroutines" from CppCon2016 (Timing 1:40 - 6:00) [this video] . Imagine that we want to establish TCP connection and get data from TCP connection: int64_t tcp_reader(int64_t total) { std::array<char, 4096> buffer; tcp::connection the_connection = tcp::connect("127.0.0.1", 1337); int64_t remaining = total; for (;;) { int64_t bytes_read = the_connection.read(buffer.data(), buffer.size()).get(); remaining -= bytes_read; i

Cites user2449761 · 2021-02 · Stack Overflow · on “Can coroutine return std::future? (unable to find the promise type for this coroutine)”

I have tried to compile coroutine example from the CppCon presentation [this video] [LINK] Unfortunately compilation fails: $ g++-10 -pedantic -Wall -std=c++20 -fcoroutines main.cpp main.cpp: In function ‘std::future<int> compute_value()’: main.cpp:7:16: error: unable to find the promise type for this coroutine 7 | int result = co_await std::async([] | ^~~~~~~~ At the beginning presenter warns that what he is about to present is just a proposal. So it makes me confused: can std::future be return from a coroutine, or do I just try to call it incorrectly? Full code: #include <coroutine> #include <iostream> #include <future> std::future<int> compute_value(){ int result = co_await std::async([] { ret