C++ Logo

std-proposals

Advanced search

Re: [std-proposals] When does vector::push_back() invalidation happen?

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Sun, 31 Mar 2024 18:28:49 +0100
On Sun, 31 Mar 2024, 16:52 Thiago Macieira via Std-Proposals, <
std-proposals_at_[hidden]> wrote:

> On Sunday, 31 March 2024 08:22:05 PDT Avi Kivity via Std-Proposals wrote:
> > If it
> > reallocates after the push_back(), and the move constructor can throw,
> > then we lose the strong exception guarantee.
>
> It's impossible to reallocate after, because the vector must create space
> to
> store the new element. It can't store the element where there's no room.
>
> > The standard says:
> > > Remarks: Causes reallocation if the new size is greater than the old
> >
> > capacity. Reallocation invalidates all the references, pointers, and
> > iterators referring to the elements in the sequence, as well as the
> > past-the-end iterator.
> >
> > So, it says nothing about whether a push_back referring to a vector
> > element is legal.
> >
> > Is this undefined behavior? Should it be specified to work? Should it
> > be noted that it is dangerous?
>
> Looks pretty clear to me: if the new size is going to be bigger than the
> previous capacity, then it invalidates and therefore the reference stored
> by
> binding the parameter to v.back() is dangling. It's clearly UB to
> dereference
> it and therefore not expected to work.
>

No, it's guaranteed to work. v.push_back(std::move(v.back())) doesn't have
to work, but Avi's example does. The standard says the argument is pushed
back, it doesn't say "unless it aliases the container".

This has been well understood and thoroughly tested by implementers for
decades.

Received on 2024-03-31 17:30:08