https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120390
Bug ID: 120390 Summary: Request to improve error with private destructor Product: gcc Version: 14.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: nightstrike at gmail dot com Target Milestone: --- I recently encountered this exact problem: https://web.archive.org/web/20250521203035/https://stackoverflow.com/questions/67962227/static-assert-failed-because-value-type-is-destructible-for-stdvector (which I conveniently saved to archive.org for whoever reads this in 20 years.) Since that post is effectively the same as my own issue, I'm reposting that (shortened) code instead of my own: ``` #include <vector> class MovieData { MovieData(){} ~MovieData(){} }; int main() { std::vector<MovieData> movies; // Line 16 return 0; } ``` On old gcc 4.8.2, we get a loud but ultimately useful error output: /usr/include/c++/4.8.2/bits/stl_construct.h: In instantiation of ‘void std::_Destroy(_Tp*) [with _Tp = MovieData]’: /usr/include/c++/4.8.2/bits/stl_construct.h:103:46: required from ‘static void std::_Destroy_aux<<anonymous> >::__destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = MovieData*; bool <anonymous> = false]’ /usr/include/c++/4.8.2/bits/stl_construct.h:127:27: required from ‘void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = MovieData*]’ /usr/include/c++/4.8.2/bits/stl_construct.h:151:31: required from ‘void std::_Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with _ForwardIterator = MovieData*; _Tp = MovieData]’ /usr/include/c++/4.8.2/bits/stl_vector.h:416:30: required from ‘std::vector<_Tp, _Alloc>::~vector() [with _Tp = MovieData; _Alloc = std::allocator<MovieData>]’ a.cc:9:29: required from here a.cc:5:10: error: ‘MovieData::~MovieData()’ is private ~MovieData(){} ^ In file included from /usr/include/c++/4.8.2/vector:62:0, from a.cc:1: /usr/include/c++/4.8.2/bits/stl_construct.h:93:7: error: within this context { __pointer->~_Tp(); } ^ Specifically, "error: ‘MovieData::~MovieData()’ is private". This is great! However, on 14.1, we get the more verbose and less helpful output: In file included from /tmp/gcc-14.1-rh7/include/c++/14.1.0/vector:64, from a.cc:1: /tmp/gcc-14.1-rh7/include/c++/14.1.0/bits/stl_construct.h: In instantiation of 'void std::_Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = MovieData*]': /tmp/gcc-14.1-rh7/include/c++/14.1.0/bits/alloc_traits.h:944:20: required from 'void std::_Destroy(_ForwardIterator, _ForwardIterator, allocator<_T2>&) [with _ForwardIterator = MovieData*; _Tp = MovieData]' 944 | std::_Destroy(__first, __last); | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ /tmp/gcc-14.1-rh7/include/c++/14.1.0/bits/stl_vector.h:735:15: required from 'std::vector<_Tp, _Alloc>::~vector() [with _Tp = MovieData; _Alloc = std::allocator<MovieData>]' 735 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 736 | _M_get_Tp_allocator()); | ~~~~~~~~~~~~~~~~~~~~~~ a.cc:9:29: required from here 9 | std::vector<MovieData> movies; // Line 16 | ^~~~~~ /tmp/gcc-14.1-rh7/include/c++/14.1.0/bits/stl_construct.h:188:51: error: static assertion failed: value type is destructible 188 | static_assert(is_destructible<_Value_type>::value, | ^~~~~ /tmp/gcc-14.1-rh7/include/c++/14.1.0/bits/stl_construct.h:188:51: note: 'std::integral_constant<bool, false>::value' evaluates to false There are a few things that made this difficult to track down. Obviously, the original message describing the core problem is gone -- that the destructor is private. Instead, it's replaced with "value type is destructible", which is confusing. At first glance, when I looked at the code, I thought "Of course it's destructible, there's the destructor!" And when I removed the destructor, it compiled perfectly. This was puzzling, and the error output sent me in ambiguous circles. Now, obviously, I should have recognized that either 1) I was missing private:, or 2) I was using class, not struct, but I'm a flawed human that makes mistakes. It'd be awesome if the compiler could help me make fewer of them :)