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?)
Disclaimer: I work for Microsoft.
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 (
/asyncand/async:strict). I seem to have the old, non–standard-compliant version turned on.The standard is clear that you cannot use plain
returnstatements in coroutines (emphasis added):— https://en.cppreference.com/w/cpp/language/coroutines
You can verify that this is a legacy behavior with a simple example (view in Godbolt):
With the
x64 msvc v19.latestcompiler and the/std:c++20flag, we get this error:So, to answer the questions:
It's not a bug in the compiler, it's just a non-standard implementation. If you use the standard implementation (with
/async:strictor/std:c++20), that plainreturnstatement will not compile. Standards-compliant coroutines cannot use plain return statements, ever.