协程有一个初始挂起点和一个最终挂起点。当coroutine_handle
在最终挂起点挂起时,它就是done
。然而,这种悬浮是通过co_await promise.final_suspend()
完成的。此函数可以返回std::never_suspend
或类似的可等待对象。
所以…然后会发生什么?如果协程在最终挂起点挂起,coroutine_handle::resume
会产生UB,但是如果超过最终挂起点会发生什么?
可以推测,协程不会被认为挂起,因此根据该规则resume
是UB。但是,对于超过最后挂起点的协程句柄,您可以做些什么呢?
或者让final_suspend
返回std::suspend_always
以外的任何值都没有意义吗?
协程函数是通过协程主体的转换来定义的。协程主体完成并退出后(通过co_return
或在块的末尾运行),将出现以下代码:
co_await p.final_suspend();
//destruct promise p
//destruct parameters in coroutine frame
//destroy coroutine state
其中p
是协程的promise对象。因此,如果final_suspend
没有引起co_await
的挂起,则承诺被销毁,随后是协程帧的参数,然后是协程状态对象本身。
coroutine_handle
引用协程状态。如果它已被销毁,则句柄不会引用挂起的协程(因为没有协程)。因此,resume
将具有未定义的行为。如果句柄没有挂起(因为它不是句柄),done
类似地具有UB。