C++协同程序可以包含纯"return"语句吗



我正在使用C++/WinRT:为UWP控件编写C++协程

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;
}

这对我来说是在编译,但据我所知,C++协程不允许使用纯return语句。这是编译器中的错误吗?

(有趣的是,我无法将co_return更改为return;我遇到了一个编译器错误。是不是只有在co_awaitco_yield之后的返回语句必须是co_return?(

免责声明:我在微软工作

这似乎是MSVSC的遗留实现。MSVSC在标准正式完成之前实现了协程,因此有两种异步实现(/async/async:strict(。我似乎打开了旧的、不符合标准的版本

标准很清楚,您不能在协同程序中使用普通的return语句(增加了强调(:

推论不能使用可变参数、纯返回语句或占位符返回类型(auto或Concept(。Constexpr函数、构造函数、析构函数和主函数不能是协程。

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

您可以通过一个简单的示例(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();
}

使用x64 msvc v19.latest编译器和/std:c++20标志,我们会得到以下错误:

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

因此,要回答以下问题:

这是为我编译的,但据我所知,C++协程不允许使用纯return语句。这是编译器中的错误吗?

(有趣的是,我无法将co_return更改为return;我遇到编译器错误。是不是只有在co_awaitco_yield之后的返回语句必须是co_return?(

这不是编译器中的错误,它只是一个非标准的实现。如果使用标准实现(带有/async:strict/std:c++20(,则不会编译该普通的return语句。符合标准的协同程序不能使用纯返回语句。

最新更新