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 :)