https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124121
--- Comment #17 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #16)
> But performing pointer arithmetic like &_M_elems[0] + 2 is UB unless there's
> an array there, and we never created an array. We just have a collection of
> unrelated T objects, floating in memory. They're not members of the same
> array, so we can't use pointer arithmetic to get from one to the next (so
> can't iterate over the container).
This is similar to how you can't use pointer arithmetic to get from a to b
here:
struct S { T a; T b; T c; } s;
assert( (&s.a + 2) == &s.c );
The addresses are the same, but &s.a + 2 is UB, because it goes past the end of
the object.
If we just use placement new to create elems[0] and elems[1] and elems[2] we
have three objects, but (according to the standard) there's still no array that
contains them.