c++ 协程 final_suspend for promise_type

c++ coroutines final_suspend for promise_type

下面是测试空协程与 promise_type

一起玩的片段
#include <iostream>
#include <coroutine>

#define DEBUG std::cout << __PRETTY_FUNCTION__ << std::endl

struct TaskSuspendAll {
      // must be of this name
    struct promise_type {
          TaskSuspendAll get_return_object() noexcept {
              return TaskSuspendAll{
                std::coroutine_handle<promise_type>::from_promise(*this)
              };
          }
        std::suspend_always initial_suspend() noexcept { 
            DEBUG;
            return {}; 
        }
        std::suspend_always final_suspend() noexcept {
              DEBUG;
              return {};
          }
          void unhandled_exception() {}
          void return_void() {
              DEBUG;
          }
      };

    std::coroutine_handle<promise_type> ch;
  };

TaskSuspendAll TestSuspendAll() {
    DEBUG;
    co_return;
}

int main() {
    std::cout << std::endl;
    auto t = TestSuspendAll();
    t.ch.resume();
    //t.ch.resume()
    //t.ch.destroy();

    return 0;
}

运行这个我得到


std::__n4861::suspend_always TaskSuspendAll::promise_type::initial_suspend()
TaskSuspendAll TestSuspendAll()
void TaskSuspendAll::promise_type::return_void()
std::__n4861::suspend_always TaskSuspendAll::promise_type::final_suspend()

我的理解是co_await应用于initial_suspendfinal_suspend。当我在 main 函数中调用 TestSuspendAll 时,它最终会调用 co_await promise.initial_suspend() 和 return 给调用者,因为我有 std::suspend_always 可等待。然后我恢复协程并执行 body 。在某些时候,我们将 co_await promise.final_suspend() 并再次 return 给来电者。

问题:我希望我必须进行第二次调用以恢复协程,以便 co_await promise.final_suspend() 成功并完成协程。但是,这会导致段错误。我知道在已完成的协程上调用 resume 是未定义的行为,但据我所知,它还没有 100% 完成。我的期望是 final_suspend 的行为与 initial_suspend 相同......这里的逻辑是什么?是我们必须在调用 final_suspend 后使用 destroy 吗?

非常感谢您的澄清!

VK

在其最终挂起点挂起是协程正在完成的定义。字面上地; that's what coroutine_handle::done returns. Attempting to resume such a coroutine is UB.

所以你的期望是不正确的。