C++ Logo

std-proposals

Advanced search

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

From: Avi Kivity <avi_at_[hidden]>
Date: Sun, 31 Mar 2024 20:50:41 +0300
On Sun, 2024-03-31 at 18:28 +0100, Jonathan Wakely via Std-Proposals
wrote:
>
>
> 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.
>
>


Yes, it was reported to me that libstdc++'s std::vector works.

But, it's not clear from the wording. I'm sure that if the move
constructor accesses the vector (via some side channel) it won't work.
To be clear the standard has to define the ordering between the new T's
construction and the resize.


Received on 2024-03-31 17:50:47