https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89311

            Bug ID: 89311
           Summary: Brace initialization needlessly invokes destructor
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: raphael.kubo.da.costa at intel dot com
  Target Milestone: ---

This is related to bug 85552 and bug 57082 as far as I can see.

GCC and ICC fail to compile this (I'm using -std=gnu++14), whereas MSVC and
clang accept it:

#include <vector>

template <class T>
struct S {
  ~S() {
    for (size_t i = 0; i < sources_.size(); ++i)
      sources_[i]->frob();
  }
 private:
  std::vector<T*> sources_;
};

class C;

struct T {
  S<C> s_{};
};

<source>: In instantiation of 'S<Source>::~S() [with T = C]':
<source>:16:11:   required from here
<source>:7:20: error: invalid use of incomplete type 'class C'
    7 |       sources_[i]->frob();
      |       ~~~~~~~~~~~~~^~~~
<source>:13:7: note: forward declaration of 'class C'
   13 | class C;
      |       ^

which ends up requiring C to be fully declared before it can be used in T.

I think https://bugs.llvm.org/show_bug.cgi?id=39363#c8 touches upon this in
"The list-initialization case does not potentially-invoke the destructor in
C++11 or C++14 either (unlike non-list copy-initialization, list-initialization
directly executes a constructor on the destination object even in C++11, and as
a result there is no temporary object created to trigger the potential
invocation of a destructor). Clang gets that case right, but GCC has another
bug there".

Reply via email to