C++ Logo


Advanced search

Re: On "transparently replaceable" in std::vector operations

From: Christopher Hallock <christopherhallock_at_[hidden]>
Date: Thu, 29 Apr 2021 01:33:17 -0400
On Wed, Apr 28, 2021 at 5:40 PM Giuseppe D'Angelo via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Hello,
> On 28/04/2021 16:55, Christopher Hallock via Std-Discussion wrote:
> > This kind of Library provision, saying that iterators, pointers,
> > and references to elements are invalidated upon condition X,
> > seems overly broad even if you don't care about using pointers
> > in an "index-like" way, because it means you can't safely use an
> > element type that stores (and properly updates across
> > moves/copies) the 'this' pointer as a member. I suspect that the
> > real intent of this kind of provision is that it only applies to
> > iterators, pointers, and references obtained through the
> > container's API.
> >
> >
> > Gah, never mind. On further reflection, this is not actually a
> > problem because the member would be overwritten on copy/move.
> >
> >
> > On even further reflection, I retract my retraction. It would
> > definitely be a problem if the invalidation occurs after the elements
> > are moved/copied. It would also be a problem if the invalidation occurs
> > beforehand and the move/copy operation involves indirecting through the
> > original element's pointer member.
> Apologies; I'm not sure if I understand the counter-counter objection.
> I was definitely talking about pointers obtained via the container's own
> APIs (data(), or & + operator[]/at(), &*it, etc.), and not pointers that
> the stored objects might be tracking themselves (for instance by adding
> themselves to some external "registry", or by having a member pointer
> equal to `this`, or so.).
> Is the objection related about "what happens if the objects stored in
> the container use container-API-derived pointers from their
> constructors, assignment operators etc. WHILE the container is
> performing a modification -- insertion, erasure, etc."?

I was adding my own concerns about these library clauses being
underspecified and overly broad. Getting back to your original question,
which is whether library invalidation "sticks", given [basic.life]/8: I
believe it does. If the invalidating operation move-assigns or copy-assigns
the elements, then [basic.life]/8 doesn't even apply because no new object
was created. If the invalidating operation move-constructs or
copy-constructs the elements, then there is room for ambiguity, but I think
the intent is that even in this case, the invalidation "sticks". I believe
things happen in this sequence: 1) element is destroyed, which
automatically invalidates pointers to it; 2) new element is created in the
same place, "resurrecting" the old pointers via [basic.life]/8; 3) the
library clause kicks in and invalidates the resurrected pointers once more.

Received on 2021-04-29 00:33:33