https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95599
--- Comment #3 from Lewis Baker <lewissbaker.opensource at gmail dot com> --- I don't think that whether or not the awaitables or operands to co_yield are captured by reference / aliased should play into the sequencing of calls to the destructor. The destructors of temporaries should always be sequenced to occur at the semicolon, which will always happen after the coroutine resumes. For another clearer example, see https://godbolt.org/z/tKQVnb e.g. changing the example ---------- struct resource { int x; resource(int x) : x(x) { std::printf("resource(%i)\n", x); } ~resource() { std::printf("~resource(%i)\n", x); } resource(resource&&) = delete; }; generator<int> f() { (resource{1}, co_yield resource{2}); } ---------- Here we are creating temporaries and sequencing expressions using operator,(). The destructor of both resource{1} and resource{2} should both occur at the semicolon, after the coroutine suspends and resumes, regardless of whether the object is captured by reference in an awaitable. ie. the expected output of the modified program should be (this is what clang does): ``` resource(1) resource(2) awaitable::await_suspend() awaitable::await_resume() ~resource(2) ~resource(1) ``` But the observed output with GCC is: ``` resource(2) awaitable::await_suspend() resource(1) awaitable::await_resume() ~resource(1) ``` Also, I'm not sure why GCC is evaluating the second operand to operator,() first and why it is constructing resource{1} _after_ the coroutine has suspended. Nothing should happen in the coroutine body between await_suspend() and await_resume().