CodeBlanks Logo Icon CodeBlanks

co_return

Learn coroutine return with co_return.

What is co_return?

co_return finishes a coroutine and returns a value. It is used instead of normal return in coroutines. co_return v; calls the return_value(v) member of the promise.

For a valueless finish, co_return; (empty) is used; this calls return_void(). A coroutine either ends with co_return or reaches the end of its body. The return keyword cannot be used inside a coroutine; co_return is written instead.

promise_type::return_value

When a coroutine ends with co_return v;, the return_value(v) member of the promise is called. This member is used to store the return value.

Example: void return_value(int v) { value_ = v; }. Here the value is written into value_. After the coroutine finishes, you can read this value with handle.promise().value_. This way the result of the coroutine is read from outside in a type-safe way. If final_suspend returns suspend_always, the frame stays alive and the value can be read.

Practice Return a value with co_return

Write co_return 10; in the body of the compute coroutine. In main get the value with promise().value_ from the result of compute() and print it with std::cout.

Starter code

main.cpp
#include <iostream>
#include <coroutine>

struct Task {
    struct promise_type {
        int value_;
        Task get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_value(int v) { value_ = v; }
        void unhandled_exception() { }
    };
    std::coroutine_handle<promise_type> handle;
};

Task compute() {
    // Return 10 with co_return
}

int main() {
    // Call compute and print the value
    return 0;
}

Sample solution

main.cpp
#include <iostream>
#include <coroutine>

struct Task {
    struct promise_type {
        int value_;
        Task get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_value(int v) { value_ = v; }
        void unhandled_exception() { }
    };
    std::coroutine_handle<promise_type> handle;
};

Task compute() {
    co_return 10;
}

int main() {
    auto t = compute();
    std::cout << t.handle.promise().value_;
    return 0;
}

Expected output

10

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Match each expression to its role

Term Meaning
co_return 42; Valued finish
co_return; Valueless finish
return_value Stores the value
return_void Empty finish

2 What is the difference between co_return and return?

  • co_return is used inside a coroutine; return cannot be used Correct answer
  • return is faster
  • co_return only returns void
  • There is no difference

Explanation: return cannot be used inside a coroutine; co_return is written instead.

3 the co_return expression

Question
Task compute() { ____ 10; }
Answer
Task compute() { co_return 10; }

Explanation: co_return 10; finishes the coroutine and returns 10.

All lessons in Advanced