【问题标题】:Why does coroutine_handle's operator bool return true after destruction?为什么coroutine_handle的操作符bool销毁后返回true?
【发布时间】:2021-09-23 16:40:50
【问题描述】:

我是 C++20 协程的新手,很惊讶coroutine_handle::operator bool 在销毁后返回 true

示例程序:

#include <coroutine>
#include <iostream>

struct ReturnObject {
  struct promise_type {
    void return_void() {}
    ReturnObject get_return_object() { return {}; }
    std::suspend_never initial_suspend() { return {}; }
    std::suspend_never final_suspend() noexcept { return {}; }
    void unhandled_exception() {}
  };
};

struct Awaiter {
  std::coroutine_handle<> *hp_;
  constexpr bool await_ready() const noexcept { return false; }
  void await_suspend(std::coroutine_handle<> h) { *hp_ = h; }
  constexpr void await_resume() const noexcept {}
};

ReturnObject
counter(std::coroutine_handle<> *continuation_out)
{
  Awaiter a{continuation_out};
  for (;;)
    co_await a;
}

int main()
{
  std::coroutine_handle<> h;
  std::cout << "before construction " << (bool)h << '\n';
  counter(&h);
  std::cout << "after construction " << (bool)h << '\n';
  h.destroy();
  std::cout << "after destruction " << (bool)h << '\n';
}

https://gcc.godbolt.org/z/a7ehjzhab

打印出来

before construction 0
after construction 1
after destruction 1

为什么销毁后还是返回true?所以无法区分活跃的coroutine_handle 和已破坏的coroutine_handle

【问题讨论】:

    标签: c++ c++-coroutine


    【解决方案1】:

    因为协程句柄基本上只是保存一个地址。您几乎可以将其视为“协程视图”,它不拥有协程。 destroy exists if the coroutine wouldn't exit normally 通过标准控制流程,例如发电机。 operator bool 对于 std::coroutine_handle 的定义等同于 return (bool)address();,除非它来自 noop 承诺(在这种情况下,它只是 true)。

    因此,当您调用 .destroy() 时,没有要求(我可以找到)句柄将自己设置回 nullptr,因为在调用 destroy 之后对句柄进行任何操作(甚至检查 operator bool)尽我所能说出未定义的行为。

    所以无法区分活动的 coroutine_handle 和被破坏的?

    真的没有?你不是故意的。一旦destroy 被调用,您应该摆脱句柄或重新初始化它(使用nullptr 或协程)。

    【讨论】:

      猜你喜欢
      • 2012-09-26
      • 2019-12-05
      • 1970-01-01
      • 2012-01-30
      • 2018-05-27
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多