Возобновление 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() называется.

Другие вопросы по тегам