https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80683
Bug ID: 80683 Summary: Exceptions don't propagate through default member initializer Product: gcc Version: 6.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: majerech.o at gmail dot com Target Milestone: --- Testcase: #include <iostream> #include <stdexcept> struct bar { bar() { throw std::runtime_error{"foo"}; } }; struct foo { bar b{}; }; int main() try { foo f; } catch (std::runtime_error& e) { std::cerr << e.what() << '\n'; } Running this results in terminate being called: terminate called after throwing an instance of 'std::runtime_error' what(): foo I would very much expect this code to work – i.e. the exception should be caught in main. This code does work on Clang 3.9.1 and I couldn't find any reason in the standard for why the exception shouldn't be allowed to propagate. Stepping through the code in GDB reveals that after throwing, the call-stack unwinds all the way to foo's constructor and goes to std::terminate from there, as if foo::foo() were noexcept. Changing foo to struct foo { bar b; }; makes the bug go away. I.e. it only happens when a default member initializer is used. I've reproduced this on GCC 6.3.1 and GCC 8.0.0 20170507.