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

--- Comment #43 from Richard Biener <rguenth at gcc dot gnu.org> ---
(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'.

Reply via email to