Суть проблемы заключается в том, что функция-член awaitable await_suspend может иметь любой из трех разных возвращаемых значений. типы: если он возвращает void, сопрограмма остается приостановленной. Если он возвращает bool, сопрограмма возобновляется для false и остается приостановленной для true. Если он возвращает std::coroutine_handle, эта сопрограмма возобновляется.
Я протестировал поведение всех этих результатов с помощью возвращаемого значения Final_suspend , и все три MSVC, Clang и GCC сходятся в этом поведении для ожидаемого объекта, где await_ready всегда возвращает false:
- Если Final_suspend().await_suspend(handle) возвращает void, сопрограмма остается приостановленной в конечной точке приостановки, как и ожидалось.
- Если Final_suspend().await_suspend( handle) возвращает bool(true), в этом случае сопрограмма также остается приостановленной в конечной точке приостановки.
- Если Final_suspend().await_suspend(handle) возвращает bool(false), что интересно, сопрограмма автоматически уничтожается, что видно по выполняемому деструктору типа обещания. Это соответствует поведению std::suspend_never и показывает, что решение может быть принято во время выполнения. Также интересно отметить, что await_resume вызывается и перед уничтожением сопрограммы, даже если ее результат отбрасывается.
- If Final_suspend().await_suspend(handle) возвращает дескриптор другой сопрограммы, эта сопрограмма возобновляется, как и ожидалось, а текущая сопрограмма остается приостановленной в конечной точке приостановки.
- Если Final_suspend().await_suspend(handle) возвращает задан тот же дескриптор, программа выходит из строя!
Мой вопрос в том, где именно эти конкретные результаты описаны или обязательны в Стандарт С++? Когда я смотрю, я не могу найти многого. Стандарт выглядит довольно кратким в описании поведения сопрограммы. Кажется, что особое поведение awaitable Final_suspend важно задокументировать, но я не могу его найти. Я могу найти заявление о том, что Final_suspend и использование его ожидаемого значения должно быть noException («не должно быть потенциально выбрасывающим»), но это все, что касается специальных правил. исходить из того, что я могу найти. Какой раздел мне не хватает? Почему возврат того же самого переданного дескриптора приводит к иному поведению, чем возврат false?
Подробнее здесь: https://stackoverflow.com/questions/783 ... coroutines