In the following program there are two coroutines. coroutine_A is empty and simply calls co_return, and coroutine_B just switches to the first coroutine once by calling co_await.
Also the program prints every time a task object is created or destructed and each time the methods await_ready and await_suspend are called:
#include <coroutine>
#include <iostream>
struct task {
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
task(handle_type h) : handle(h) {
std::cout << "task ctor " << this << '\n';
}
~task() {
std::cout << "task dtor " << this << '\n';
}
struct promise_type {
auto get_return_object() {
return task{handle_type::from_promise(*this)};
}
auto initial_suspend() {
return std::suspend_always {};
}
auto unhandled_exception() {}
auto final_suspend() noexcept {
return std::suspend_always{};
}
void return_void() {}
};
handle_type handle;
void await_resume() {
std::cout << "await_resume " << this << '\n';
handle.resume();
}
auto await_suspend(handle_type) {
std::cout << "await_suspend " << this << '\n';
return handle;
}
auto await_ready() {
std::cout << "await_ready " << this << '\n';
return false;
}
};
int main() {
task coroutine_A = []() ->task {
co_return;
}();
task coroutine_B = [&coroutine_A]() ->task {
co_await coroutine_A;
}();
coroutine_B.handle.resume();
}
What surprises me is that the program built by GCC prints here, for example:
task ctor 0x7ffdef0f9458
task ctor 0x7ffdef0f9450
await_ready 0x431f30
await_suspend 0x431f30
task dtor 0x7ffdef0f9450
task dtor 0x7ffdef0f9458
Please note that this inside task::await_ready and task::await_suspendis not equal to any constructed instance of task. Demo: https://gcc.godbolt.org/z/WPnGqdhjr
Is it a GCC bug or there is some other explanation?