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.