c++visual-studio-2019c++20c++-coroutine

"a coroutine's promise must declare either 'return_value' or 'return_void'" Error Visual Studio 2019 C++ 20


VS2019 latest c++ compiler.

Error is :"a coroutine's promise must declare either 'return_value' or 'return_void'"

Example pulled from David Mazièreshttps://www.scs.stanford.edu/~dm/blog/c++-coroutines.html blog that works under a different compiler,GCC 10.2.

I can't get the source code to compile in VS2019.

#include <concepts>
#include <coroutine>
#include <exception>
#include <iostream>
struct ReturnObject {
    struct promise_type {
        ReturnObject get_return_object() { return {}; }
        std::suspend_never initial_suspend() { return {}; }
        std::suspend_never final_suspend() noexcept { return{}; }
        void unhandled_exception() {}
        
    };
};

struct Awaiter {
    std::coroutine_handle<>* hp_;
    constexpr bool await_ready() const noexcept { return false; }
    void await_suspend(std::coroutine_handle<> h) { *hp_ = h; }
    constexpr void await_resume() const noexcept {}
};

ReturnObject
counter(std::coroutine_handle<>* continuation_out)
{
    Awaiter a{ continuation_out };
    for (unsigned i = 0;; ++i) {
        co_await a;
        std::cout << "counter: " << i << std::endl;
    }
}

void
main1()
{
    std::coroutine_handle<> h;
    counter(&h);                
    for (int i = 0; i < 100; ++i) {
        std::cout << "In main1 function\n";
        h();
    }
    h.destroy();
}

What am I missing? New to coroutines in C++. Who isn't?


Solution

  • This answer is incorrect. Please see another answer.


    Both compilers are correct. Flowing off the end of a coroutine when the promise type doesn't have return_void is undefined behaviour:

    [stmt.return.coroutine]/3:

    If p.return_­void() is a valid expression, flowing off the end of a coroutine is equivalent to a co_­return with no operand; otherwise flowing off the end of a coroutine results in undefined behavior.

    You can define a noop return_void in the promise type to get the behaviour you seem to be going for:

    void return_void() noexcept {}