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]).

所以编译器应该认为代码格式不正确并发出错误。