https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124121
--- Comment #21 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 19 Feb 2026, redi at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124121 > > --- Comment #16 from Jonathan Wakely <redi at gcc dot gnu.org> --- > Placement new will only create the lifetime of a T at a particular location > (which happens to be within the storage for an array in the union). > > 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). > > The pointer arithmetic works for std::vector because heap memory (created by > malloc, or operator new) has magic properties that "implicitly create > objects". > There's no equivalent magic for an uninitialized union { T elems[N]; } in a > stack variable. > > So the point of the start_lifetime_as_array call is to create an array > "around" > the individual T objects, like a frame to hold them in. Because the standard > requires it. > > If GCC (and Clang, when it uses out headers) don't actually care about that > rule in the standard, then we can remove the start_lifetime_as_array call. GCC doesn't care about pointer arithmetic, only about actual accesses to objects.
