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

Reply via email to