https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113745

            Bug ID: 113745
           Summary: Poor diagnostics quality for resize() without a
                    default-constructible type
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: janschultke at googlemail dot com
  Target Milestone: ---

## Code to reproduce (https://godbolt.org/z/6ETnffr8c)

#include <vector>

struct non_default_constructible {
    non_default_constructible(int) {}
};

int main() {
    std::vector<non_default_constructible> v;
    v.resize(0);
}


## Diagnostic

In file included from
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_iterator.h:78,
                 from
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_algobase.h:67,
                 from
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/vector:62,
                 from <source>:1:
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:
In instantiation of 'constexpr void std::_Construct(_Tp*, _Args&& ...) [with
_Tp = non_default_constructible; _Args = {}]':
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:643:18:
  required from 'static constexpr _ForwardIterator
std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator,
_Size) [with _ForwardIterator = non_default_constructible*; _Size = long
unsigned int; bool _TrivialValueType = false]'
  643 |                 std::_Construct(std::__addressof(*__cur));
      |                 ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:701:22:
  required from 'constexpr _ForwardIterator
std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator
= non_default_constructible*; _Size = long unsigned int]'
  700 |         return __uninitialized_default_n_1<false>::
      |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  701 |                  __uninit_default_n(__first, __n);
      |                  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:779:44:
  required from 'constexpr _ForwardIterator
std::__uninitialized_default_n_a(_ForwardIterator, _Size, allocator<_Tp>&)
[with _ForwardIterator = non_default_constructible*; _Size = long unsigned int;
_Tp = non_default_constructible]'
  779 |     { return std::__uninitialized_default_n(__first, __n); }
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/vector.tcc:821:35:
  required from 'constexpr void std::vector<_Tp,
_Alloc>::_M_default_append(size_type) [with _Tp = non_default_constructible;
_Alloc = std::allocator<non_default_constructible>; size_type = long unsigned
int]'
  821 |                
std::__uninitialized_default_n_a(this->_M_impl._M_finish,
      |                
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
  822 |                                                  __n,
_M_get_Tp_allocator());
      |                                                 
~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_vector.h:1013:4:
  required from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type)
[with _Tp = non_default_constructible; _Alloc =
std::allocator<non_default_constructible>; size_type = long unsigned int]'
 1013 |           _M_default_append(__new_size - size());
      |           ^~~~~~~~~~~~~~~~~
<source>:9:13:   required from here
    9 |     v.resize(0);
      |     ~~~~~~~~^~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:115:28:
error: no matching function for call to
'construct_at(non_default_constructible*&)'
  115 |           std::construct_at(__p, std::forward<_Args>(__args)...);
      |           ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note: candidate: 'template<class _Tp, class ... _Args> constexpr decltype
(::new(void*(0)) _Tp) std::construct_at(_Tp*, _Args&& ...)'
   94 |     construct_at(_Tp* __location, _Args&&... __args)
      |     ^~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:   template argument deduction/substitution failed:
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:
In substitution of 'template<class _Tp, class ... _Args> constexpr decltype
(::new(void*(0)) _Tp) std::construct_at(_Tp*, _Args&& ...) [with _Tp =
non_default_constructible; _Args = {}]':
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:115:21:
  required from 'constexpr void std::_Construct(_Tp*, _Args&& ...) [with _Tp =
non_default_constructible; _Args = {}]'
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:   115 |           std::construct_at(__p, std::forward<_Args>(__args)...);
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |           ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:643:18:
  required from 'static constexpr _ForwardIterator
std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator,
_Size) [with _ForwardIterator = non_default_constructible*; _Size = long
unsigned int; bool _TrivialValueType = false]'
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:   643 |                 std::_Construct(std::__addressof(*__cur));
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |                 ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:701:22:
  required from 'constexpr _ForwardIterator
std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator
= non_default_constructible*; _Size = long unsigned int]'
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:   700 |         return __uninitialized_default_n_1<false>::
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     701 |                  __uninit_default_n(__first, __n);
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |                  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:779:44:
  required from 'constexpr _ForwardIterator
std::__uninitialized_default_n_a(_ForwardIterator, _Size, allocator<_Tp>&)
[with _ForwardIterator = non_default_constructible*; _Size = long unsigned int;
_Tp = non_default_constructible]'
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:   779 |     { return std::__uninitialized_default_n(__first, __n); }
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/vector.tcc:821:35:
  required from 'constexpr void std::vector<_Tp,
_Alloc>::_M_default_append(size_type) [with _Tp = non_default_constructible;
_Alloc = std::allocator<non_default_constructible>; size_type = long unsigned
int]'
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:   821 |                
std::__uninitialized_default_n_a(this->_M_impl._M_finish,
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |                
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
     822 |                                                  __n,
_M_get_Tp_allocator());
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |                                                 
~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_vector.h:1013:4:
  required from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type)
[with _Tp = non_default_constructible; _Alloc =
std::allocator<non_default_constructible>; size_type = long unsigned int]'
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:  1013 |           _M_default_append(__new_size - size());
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |           ^~~~~~~~~~~~~~~~~
<source>:9:13:   required from here
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:     9 |     v.resize(0);
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:94:5:
note:       |     ~~~~~~~~^~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:96:17:
error: no matching function for call to
'non_default_constructible::non_default_constructible()'
   96 |     -> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:4:5: note: candidate:
'non_default_constructible::non_default_constructible(int)'
    4 |     non_default_constructible(int) {}
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~
<source>:4:5: note:   candidate expects 1 argument, 0 provided
<source>:3:8: note: candidate: 'constexpr
non_default_constructible::non_default_constructible(const
non_default_constructible&)'
    3 | struct non_default_constructible {
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~
<source>:3:8: note:   candidate expects 1 argument, 0 provided
<source>:3:8: note: candidate: 'constexpr
non_default_constructible::non_default_constructible(non_default_constructible&&)'
<source>:3:8: note:   candidate expects 1 argument, 0 provided
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:
In instantiation of 'constexpr void std::_Construct(_Tp*, _Args&& ...) [with
_Tp = non_default_constructible; _Args = {}]':
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:643:18:
  required from 'static constexpr _ForwardIterator
std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator,
_Size) [with _ForwardIterator = non_default_constructible*; _Size = long
unsigned int; bool _TrivialValueType = false]'
<source>:3:8: note:   643 |                
std::_Construct(std::__addressof(*__cur));
<source>:3:8: note:       |                
~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:701:22:
  required from 'constexpr _ForwardIterator
std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator
= non_default_constructible*; _Size = long unsigned int]'
<source>:3:8: note:   700 |         return __uninitialized_default_n_1<false>::
<source>:3:8: note:       |                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     701 |                  __uninit_default_n(__first, __n);
<source>:3:8: note:       |                  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_uninitialized.h:779:44:
  required from 'constexpr _ForwardIterator
std::__uninitialized_default_n_a(_ForwardIterator, _Size, allocator<_Tp>&)
[with _ForwardIterator = non_default_constructible*; _Size = long unsigned int;
_Tp = non_default_constructible]'
<source>:3:8: note:   779 |     { return
std::__uninitialized_default_n(__first, __n); }
<source>:3:8: note:       |             
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/vector.tcc:821:35:
  required from 'constexpr void std::vector<_Tp,
_Alloc>::_M_default_append(size_type) [with _Tp = non_default_constructible;
_Alloc = std::allocator<non_default_constructible>; size_type = long unsigned
int]'
<source>:3:8: note:   821 |                
std::__uninitialized_default_n_a(this->_M_impl._M_finish,
<source>:3:8: note:       |                
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
     822 |                                                  __n,
_M_get_Tp_allocator());
<source>:3:8: note:       |                                                 
~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_vector.h:1013:4:
  required from 'constexpr void std::vector<_Tp, _Alloc>::resize(size_type)
[with _Tp = non_default_constructible; _Alloc =
std::allocator<non_default_constructible>; size_type = long unsigned int]'
<source>:3:8: note:  1013 |           _M_default_append(__new_size - size());
<source>:3:8: note:       |           ^~~~~~~~~~~~~~~~~
<source>:9:13:   required from here
<source>:3:8: note:     9 |     v.resize(0);
<source>:3:8: note:       |     ~~~~~~~~^~~
/opt/compiler-explorer/gcc-trunk-20240203/include/c++/14.0.1/bits/stl_construct.h:119:7:
error: no matching function for call to
'non_default_constructible::non_default_constructible()'
  119 |       ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:4:5: note: candidate:
'non_default_constructible::non_default_constructible(int)'
    4 |     non_default_constructible(int) {}
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~
<source>:4:5: note:   candidate expects 1 argument, 0 provided
<source>:3:8: note: candidate: 'constexpr
non_default_constructible::non_default_constructible(const
non_default_constructible&)'
    3 | struct non_default_constructible {
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~
<source>:3:8: note:   candidate expects 1 argument, 0 provided
<source>:3:8: note: candidate: 'constexpr
non_default_constructible::non_default_constructible(non_default_constructible&&)'
<source>:3:8: note:   candidate expects 1 argument, 0 provided
Compiler returned: 1


## Explanation


I find that this diagnostic is extremely confusing and verbose for what it is.
The issue is that non_default_construtible is not Cpp17DefaultInsertable, which
is required by resize() (https://eel.is/c++draft/vector.capacity#14).

Maybe we could add a static_assert to resize() which informs the user about the
issue more concisely.
  • [Bug c++/113745] New: Poor ... janschultke at googlemail dot com via Gcc-bugs

Reply via email to