https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66139
Bug ID: 66139 Summary: destructor not called for members of partially constructed anonymous struct/array Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: f.heckenb...@fh-soft.de Target Milestone: --- The attached test program tries to construct various structures consisting of two members of some type a, where construction of the first one succeeds and the second one throws, and checks whether the destructor of the first one was called before the exception is caught. Since the first member was constructed successfully, I'd expect its destructor to be called. Granted, I don't know the exact standard wording, but my general idea is that once a constructor call succeeds, an object starts to exist, thus it must at some point cease to exist, and then its destructor must be called. clang 3.5.0 and visual c++ (according to http://webcompiler.cloudapp.net/, without the GCC extension "(a[2]) { ... }") do call the destructor every time. The g++ output is: destructor called destructor not called destructor called destructor not called destructor not called destructor not called So with a named struct/array variable, the destructor gets called, with anonymous ones it doesn't. Even with a named initializer_list it doesn't, but I suppose that's because the compiler first constructs an anonymous array (and then would construct the initializer_list if it got there). #include <iostream> int c, d; struct a { a (int i) { if (i) throw i; c++; } ~a () { d++; } }; void check (void (*f) ()) { try { c = d = 0; f (); } catch (int) { std::cerr << (c != 1 ? "constructor not completed exactly once\n" : d == 0 ? "destructor not called\n" : d == 1 ? "destructor called\n" : "destructor called more than once\n"); return; } std::cerr << "exception not thrown\n"; } int main () { struct s { a x, y; }; check ([] { s t { 0, 1 }; }); check ([] { s { 0, 1 }; }); check ([] { a t[2] { 0, 1 }; }); check ([] { (a[2]) { 0, 1 }; }); check ([] { std::initializer_list <a> t { 0, 1 }; }); check ([] { std::initializer_list <a> { 0, 1 }; }); }