https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349
--- Comment #44 from Andrew Downing <andrew2085 at gmail dot com> --- (In reply to Richard Biener from comment #43) > (In reply to Andrew Downing from comment #41) > > > Thus for types without a non-trivial ctor/dtor you do not need to use > > > placement new. So take your example and remove the placement new. > > > Does that change its semantics? > > > > These are C++17 rules. > > > > 4.5/1) An object is created by a definition, by a new-expression, when > > implicitly changing the active member of a union, or when a temporary object > > is created. > > > > 6.8/1) The lifetime of an object of type T begins when: storage with the > > proper alignment and size for type T is obtained, and if the object has > > non-vacuous initialization, its initialization is complete. > > > > double d; > > > > My interpretation of the above rules would be that only a double object is > > created in the storage for d because T in 6.8/1 is set to double by the > > definition of d. According to these rules the only way to change the dynamic > > type of the object in d's storage would be with placement new (pre C++20). > > memcpy only overwrites the object representation. It doesn't affect it's > > type or lifetime. > > What would > > *(long *)&d = 1; > > do? My reading of earlier standards say it starts lifetime of a new object > of type long (the storage of 'd' gets reused). Following that stmt a read > like > > foo (d); > > invokes undefined behavior (it accesses the storage of effective type long > via an effective type of double). The same example with placement new > would be > > *(new (&d) long) = 1; > > and I'm arguing the placement new is not required to start the lifetime > of an object of type long in the storage of 'd'. It's been a while since I've though about this stuff. double d; *(long *)&d = 1; That would be lead to undefined behavior because it's breaking the strict aliasing rules. *(new (&d) long) = 1; That would be ok because new creates a long object in the storage of d before dereferencing.