c++ - co_await 之后当前处理的异常是什么?

标签 c++ exception c++20 c++-coroutine

GCC 允许从 catch 恢复 C++20 协程部分并在协程中调用 co_await再次来自其 catch部分。
在这种情况下,当前处理的异常被认为是什么?
请考虑一个例子:

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


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

关于c++ - co_await 之后当前处理的异常是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68474189/

相关文章:

c++ - 将日志消息打印到 MotionBuilder

C++ 通过引用传递

split - 如何使用 C++20 std::views::split 将 std::string_views 拆分为类似元组的对象?

c# - try catch 并重新抛出异常

c++ - 使用 C++20 using-enum-declaration 进行二义性名称查找

c++ - 为什么 C++20 中的 [[likely]] 属性会在此处引发警告?

c++ - 为什么 boost::log 的链接限制

C++:扩展模板类

c# - list <T> : Clear; AddRange; Add; Delete; ect. 。导致 System.IndexOutOfRangeException

c++ - 在异常处理程序中使用 'goto' 是不好的风格吗?