c++ exception-handling c++14 shared-ptr initializer-list

Pérdida de memoria bajo GCC(pero no Clang) cuando se lanza en medio de una lista de inicializadores de C++ 14 para std:: list<shared_ptr>



exception-handling c++14 (1)

Convertir mi comentario en una respuesta para que pueda marcar la pregunta como respondida.

Esto parece ser un error gcc

Error 66139 - destructor no llamado para miembros de estructura / array anónima parcialmente construida

Tenga en cuenta en particular los dos últimos casos de prueba que utilizan std::initializer_list para ilustrar el problema.

Considere el siguiente programa:

#include <stdexcept> #include <stdio.h> #include <memory> #include <list> class Foo { public: Foo(){ if (s_ct==0) {throw std::bad_alloc();} --s_ct; fprintf(stderr, "ctor %p/n", this); } ~Foo(){ fprintf(stderr, "dtor %p/n", this); } private: static int s_ct; }; int Foo::s_ct = 2; int main(){ try { std::list<std::shared_ptr<Foo>> l = { std::make_shared<Foo>(), std::make_shared<Foo>(), std::make_shared<Foo>() }; } catch (std::bad_alloc&) { fprintf(stderr, "caught exception./n"); } fprintf(stderr, "done./n"); return 0; }

Compilado de esta manera:

[little:~] $ g++ --version g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [little:~] $ g++ --std=c++14 -o list_init list_init.cc [little:~] $

La salida es:

[little:~] $ ./list_init ctor 0x1294c30 ctor 0x1294c50 caught exception. done. [little:~] $

Observa que los destructores no son llamados. Valgrind se queja correctamente de la fuga también.

Esto parece violar uno de los propósitos clave de std::make_shared , a saber, que si se lanza otra expresión en la declaración, el objeto compartido se destruye adecuadamente porque está envuelto por un objeto puntero compartido totalmente construido.

Clang hace lo que me gustaría aquí:

[little:~] $ clang++ --version clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin [little:~] $ clang++ --std=c++14 -o foo list_init.cc [little:~] $ ./foo ctor 0x1dfec30 ctor 0x1dfec50 dtor 0x1dfec50 dtor 0x1dfec30 caught exception. done. [little:~] $

Entonces, ¿esto es un error de GCC, o necesito arreglar mi programa?