Skip to content

[expr.await] p5 The control flow returns to the current coroutine caller or resumer only if the coroutine is still suspended #863

@xmh0511

Description

@xmh0511

Full name of submitter (unless configured in github; will be published with the issue): Jim X

[expr.await] p5 says:

The await-expression evaluates the (possibly-converted) o expression and the await-ready expression, then:

If the result of await-ready is false, the coroutine is considered suspended.
Then:

[...]
Otherwise, if the type of await-suspend is bool, await-suspend is evaluated, and the coroutine is resumed if the result is false.

If the evaluation of await-suspend exits via an exception, the exception is caught, the coroutine is resumed, and the exception is immediately rethrown ([except.throw]). Otherwise, control flow returns to the current coroutine caller or resumer ([dcl.fct.def.coroutine]) without exiting any scopes ([stmt.jump]). The point in the coroutine immediately prior to control returning to its caller or resumer is a coroutine suspend point.

Consider this example:

#include <coroutine>
#include <exception>
#include <iostream>



struct Task {
    struct promise_type {
        Task get_return_object() {
            return {std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() {}
    };

    std::coroutine_handle<promise_type> handle;

    Task(std::coroutine_handle<promise_type> h) : handle(h) {}
    ~Task() {}
};

struct SuspendOnce {
    bool await_ready() { return false; }
    bool await_suspend(std::coroutine_handle<>) { return false; }
    void await_resume() {}
};

Task my_coroutine() {
    co_await SuspendOnce{};
    std::cout<<"resume\n"; // #1
}


int main() {
    auto task = my_coroutine();
    std::cout<<"main\n";
    return 0;
}

The implementations continue to evaluate #1 without returning the control flow to the caller.

Suggested Resolution:

Otherwise, control flow returns to the current coroutine caller or resumer ([dcl.fct.def.coroutine]) without exiting any scopes ([stmt.jump]) if the coroutine is suspended

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions