Exception in aggregate initialization

  • A+

In C++14 (gcc 6.3) I have the following code:

#include <memory> #include <vector> #include <stdexcept>  struct A {     int a1;     int a2; };  struct B {     int b1;     std::shared_ptr< std::vector<A> > Alist;         };  struct C {     std::shared_ptr<B> b;     std::shared_ptr< std::vector<A> > Alist;         };      std::shared_ptr< std::vector<A> > makeListA() {     std::vector<A> toto = {{0,1}, {2,3}};     return std::make_shared< std::vector<A> >(toto); }  std::shared_ptr< std::vector<A> > makeListAWithException() {     throw std::out_of_range("My exception"); }  std::shared_ptr<B> makeB() {     return std::make_shared<B>(B{0, makeListA()}); }  main() {     std::make_unique<C>(C{makeB(),makeListAWithException()}); } 

When running valgrind i have a memory leak : it looks like the objects created by "makeB()" function were not freed. I had this problem only when using aggregate initialization with curly braces.

When I define an explicit constructor on each class (A, B and C), I don't have this issue.

What am I doing wrong ?

Best regards


This is gcc bug 66139. Here is a short reproduction, courtesy of Andrzej (with a more thorough description available in the blog post):

#include <cstdio> #include <stdexcept>  struct Resource {   explicit Resource(int) { std::puts("create"); }   Resource(Resource const&) { std::puts("create"); }   ~Resource() { std::puts("destroy"); } };  Resource make_1() { return Resource(1); } Resource make_2() { throw std::runtime_error("failed"); }  struct User  {   Resource r1;   Resource r2; };  void process (User) {}  int main() {   try {     process({make_1(), make_2()});   }   catch (...) {} } 

This prints:


It should print (as clang, correctly, does):

create destroy     


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: