Возобновление final_suspend вызывает ошибку, а не уничтожает сопрограмму
Джеймс МакНеллис в своей презентации "Введение в сопрограммы C++" ( https://youtu.be/ZTqHjjm86Bw?t=1898) говорит следующее:
Сопрограмма уничтожается, когда:
- final_suspend возобновляется,
- вызывается coroutine_handle<>::destroy(),
что произойдет первым.
В моих тестах я вижу (VS 2015, VS 2017 RC), что возобновление сопрограммы, которая приостановлена на final_suspend, вызывает ошибку:
Необработанное исключение в 0x010B9EDD в Awaits2017.exe: код инструментария RangeChecks обнаружил доступ к массиву вне диапазона. произошло
Есть идеи, что здесь может происходить?
#include <experimental/resumable>
using namespace std;
using namespace std::experimental;
struct Coro
{
coroutine_handle<> m_coro;
Coro(coroutine_handle<> coro) : m_coro(coro) {}
struct promise_type
{
Coro get_return_object()
{
return Coro(coroutine_handle<promise_type>::from_promise(*this));
}
auto initial_suspend() { return false; }
auto final_suspend() { return true; }
void return_void() {}
};
};
Coro simple()
{
co_return;
}
int main()
{
Coro c = simple();
c.m_coro.resume(); // runtime error here
}
1 ответ
Практическое правило:
Если
final_suspend
возвращаетсяtrue
позвониcoroutine_handle<>::destroy()
, вместоresume()
,Если
final_suspend
возвращаетсяfalse
не стоит звонитьdestroy()
также сопрограмма сама себя очистит.
Обратите внимание, что сопрограмма, включенная в VS 2015, - это не то, что Джеймс МакНеллис показал в видео (предложение имеет много ревизий), а описание:
final_suspend возобновлен
может быть запутанным Это на самом деле не значит resume()
называется.