co_await之后当前处理的异常是什么?
What is the currently handled exception after co_await?
GCC 允许从 catch
部分恢复 C++20 协程,并在协程中从其 catch
部分再次调用 co_await
。
在这种情况下,当前处理的异常被认为是什么?
请考虑一个例子:
#include <coroutine>
#include <iostream>
struct ReturnObject {
struct promise_type {
ReturnObject get_return_object() { return { std::coroutine_handle<promise_type>::from_promise(*this) }; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() {}
void return_void() {}
};
std::coroutine_handle<promise_type> h_;
};
ReturnObject coroutine()
{
try {
std::cout << "Exception 1 being thrown\n";
throw 1;
}
catch( int a ) {
std::cout << "Exception caught in coroutine " << a << std::endl;
co_await std::suspend_always{};
try {
std::cout << "Current exception being rethrown\n";
throw;
}
catch( int b ) {
std::cout << "Exception caught in coroutine " << b << std::endl;
}
}
}
int main()
{
auto h = coroutine().h_;
try {
std::cout << "Exception 0 being thrown" << std::endl;
throw 0;
}
catch( int a ) {
std::cout << "Exception " << a << " caught in main" << std::endl;
h();
}
h();
h.destroy();
}
它打印(https://gcc.godbolt.org/z/4deoG7Pnh):
Exception 0 being thrown
Exception 0 caught in main
Exception 1 being thrown
Exception caught in coroutine 1
Current exception being rethrown
Exception caught in coroutine 0
这里我最感兴趣的是最后一行,因为它表明 throw;
重新抛出 0
而不是 1
,这实际上是正在处理的那个。正确吗?
co_await
只能出现在 catch
块之外,如 specified by the standard:
An await-expression shall appear only in a potentially-evaluated expression within the compound-statement of a function-body outside of a handler.
co_yield
被定义为 co_await
的变体,所以它有 the same limitations:
A yield-expression shall appear only within a suspension context of a function ([expr.await]).
所以编译器应该认为代码格式不正确并发出错误。
GCC 允许从 catch
部分恢复 C++20 协程,并在协程中从其 catch
部分再次调用 co_await
。
在这种情况下,当前处理的异常被认为是什么?
请考虑一个例子:
#include <coroutine>
#include <iostream>
struct ReturnObject {
struct promise_type {
ReturnObject get_return_object() { return { std::coroutine_handle<promise_type>::from_promise(*this) }; }
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() {}
void return_void() {}
};
std::coroutine_handle<promise_type> h_;
};
ReturnObject coroutine()
{
try {
std::cout << "Exception 1 being thrown\n";
throw 1;
}
catch( int a ) {
std::cout << "Exception caught in coroutine " << a << std::endl;
co_await std::suspend_always{};
try {
std::cout << "Current exception being rethrown\n";
throw;
}
catch( int b ) {
std::cout << "Exception caught in coroutine " << b << std::endl;
}
}
}
int main()
{
auto h = coroutine().h_;
try {
std::cout << "Exception 0 being thrown" << std::endl;
throw 0;
}
catch( int a ) {
std::cout << "Exception " << a << " caught in main" << std::endl;
h();
}
h();
h.destroy();
}
它打印(https://gcc.godbolt.org/z/4deoG7Pnh):
Exception 0 being thrown
Exception 0 caught in main
Exception 1 being thrown
Exception caught in coroutine 1
Current exception being rethrown
Exception caught in coroutine 0
这里我最感兴趣的是最后一行,因为它表明 throw;
重新抛出 0
而不是 1
,这实际上是正在处理的那个。正确吗?
co_await
只能出现在 catch
块之外,如 specified by the standard:
An await-expression shall appear only in a potentially-evaluated expression within the compound-statement of a function-body outside of a handler.
co_yield
被定义为 co_await
的变体,所以它有 the same limitations:
A yield-expression shall appear only within a suspension context of a function ([expr.await]).
所以编译器应该认为代码格式不正确并发出错误。