简体   繁体   中英

Can C++ coroutines contain plain `return` statements?

I am writing a C++ coroutine for a UWP control using C++/WinRT :

winrt::fire_and_forget MyControl::DoSomething()
{
    if (/* some condition */)
    {
         // Why does this work?!
         return;
    }

    co_await winrt::resume_foreground(Dispatcher());

    // Do some stuff

    co_return;
}

This is compiling for me, but as far as I know, C++ coroutines do not allow plain return statements. Is this a bug in the compiler?

(Interestingly, I cannot change the co_return to return ; I get a compiler error. Is it that only return statements after a co_await or co_yield must be co_return ?)

This seems to be a legacy implementation for MSVSC. MSVSC implemented coroutines before the standard was formally complete, so there are two implementations of async ( /async and /async:strict ). I seem to have the old, non–standard-compliant version turned on.

The standard is clear that you cannot use plain return statements in coroutines (emphasis added):

Coroutines cannot use variadic arguments, plain return statements , or placeholder return types (auto or Concept). Constexpr functions, constructors, destructors, and the main function cannot be coroutines.

https://en.cppreference.com/w/cpp/language/coroutines

You can verify that this is a legacy behavior with a simple example ( view in Godbolt ):

// ... boilerplate to make std::futures awaitable ...
// via https://stackoverflow.com/a/70406948/788168

std::future<int> compute_value()
{
    if (rand() > 5)
    {
        // Shouldn't work:
        return 5;
    }

    int result = co_await std::async([] { return 30; });

    co_return result;
}

int main() {
    compute_value();
}

With the x64 msvc v19.latest compiler and the /std:c++20 flag, we get this error:

example.cpp
<source>(38): error C3773: Use of 'return' in this context is a non-conforming extension in C++20
<source>(38): note: Please use '/await' command-line option to enable relevant extensions
Compiler returned: 2

So, to answer the questions:

This is compiling for me, but as far as I know, C++ coroutines do not allow plain return statements. Is this a bug in the compiler?

(Interestingly, I cannot change the co_return to return ; I get a compiler error. Is it that only return statements after a co_await or co_yield must be co_return ?)

It's not a bug in the compiler, it's just a non-standard implementation. If you use the standard implementation (with /async:strict or /std:c++20 ), that plain return statement will not compiler. Standards-compliant coroutines cannot use plain return statements, ever.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM