https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110620
--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> --- That isn't necessarily true though. _S_check_init_len takes __n by non-const reference and changes it to be the number of elements that are actually allocated *which might be more than requested*. std::vector has to grow exponentially, so if the current size is 10 and we ask for 12, it will actually allocate space for 20, and set __n to 20. So the end_of_storage is start + 20, but finish is start + 12 We could make a copy of __n before the call to _S_check_init_len, and then use that: const size_type __orig_n = __n; pointer __start = this->_M_impl._M_start = this->_M_allocate(_S_check_init_len(__n, _M_get_Tp_allocator())); this->_M_impl._M_end_of_storage = __start + __n; this->_M_impl._M_finish = std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, __start, _M_get_Tp_allocator()); if (this->_M_impl._M_finish - this->_M_impl._M_start != __orig_n) __builtin_unreachable(); Or equivalently, let _S_check_init_len write to a different variable: size_type __n_allocated = __n; pointer __start = this->_M_impl._M_start = this->_M_allocate(_S_check_init_len(__n_allocated, _M_get_Tp_allocator())); this->_M_impl._M_end_of_storage = __start + __n_allocated; this->_M_impl._M_finish = std::__uninitialized_copy_a(_GLIBCXX_MOVE(__first), __last, __start, _M_get_Tp_allocator()); if (this->_M_impl._M_finish - this->_M_impl._M_start != __n) __builtin_unreachable();