N. Shead
N. Shead

Reputation: 3938

Simple coroutine leaking with GCC 10

Consider the following simple coroutine, which tracks its construction and destruction:

#include <coroutine>
#include <iostream>

struct simple {
  static inline int x = 0;
  int id = 0;
  simple() : id{ x++ } { std::cout << id << " constructed\n"; }
  simple(simple&&) : id{ x++ } { std::cout << id << " move constructed\n"; }
  ~simple() { std::cout << id << " destructed\n"; }

  struct promise_type {
    simple get_return_object() { return {}; }
    void return_void() {}
    void unhandled_exception() { std::terminate(); }
    auto initial_suspend() noexcept { return std::suspend_never{}; }
    auto final_suspend() noexcept { return std::suspend_never{}; }
  };
};

simple f() { co_return; }

int main() {
  f();
}

When compiling with GCC 10.1, the output is:

0 constructed
1 move constructed
1 destructed

—notably, id 0 is never destructed. This is true even with GCC trunk.

Is there something I've done wrong here, some hidden UB or the like? Or is GCC at fault here?

As a comparison, I tried using Clang's experimental coroutine support, and got

0 constructed
0 destructed

which is closer to what I was expecting. I also get this "correct" output even in GCC if I comment out the move constructor in the coroutine object.

Live example: https://godbolt.org/z/UQVURi

Upvotes: 13

Views: 1237

Answers (1)

N. Shead
N. Shead

Reputation: 3938

As Oliv mentioned, it appears this is just a bug with GCC's experimental coroutine support. A ticket has been raised here.

Upvotes: 1

Related Questions