https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61982

--- Comment #12 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The C++ standard. Specifically, [basic.life].

After the constructor runs and before the destructor runs, that memory location
contains an object of type X. After the destructor finishes you can reuse the
storage for another object.

The memcmp calls treats the storage as an array of unsigned char and can
implicitly begin the lifetime of an array of unsigned char because unsigned
char does not have non-vacuous initialization (i.e. it doesn't need to be
initialized). However, if you don't initialize those characters then they have
indeterminate values.

So the first memcmp call reuses the storage to create an array of unsigned char
with indeterminate values. That ends the lifetime of the X (without calling the
destructor). Then you call the destructor on an object that already ended its
lifetime, which is undefined. Then you reuse it as an array of unsigned char
again, and it still has indeterminate values.

Even if we ignore the UB caused by invoking the destructor for an object that
no logner exists, the value representation of the X cannot be inspected by
memcmp, because X is not trivially copyable, and since the values are
indeterminate there is no requirement for the values written by the destructor
to be observable.

Reply via email to