reinterpret_cast creating a trivially default-constructible object

There is no X object, living or otherwise, so pretending that there is one results in undefined behavior.

[intro.object]/1 spells out exhaustively when objects are created:

An object is created by a definition ([basic.def]), by a
new-expression ([expr.new]), when implicitly changing the active
member of a union ([class.union]), or when a temporary object is
created ([conv.rval], [class.temporary]).

With the adoption of P0137R1, this paragraph is the definition of the term “object”.

Is there a definition of an X object? No. Is there a new-expression? No. Is there a union? No. Is there a language construct in your code that creates a temporary X object? No.

Whatever [basic.life] says about the lifetime of an object with vacuous initialization is irrelevant. For that to apply, you have to have an object in the first place. You don’t.

C++11 has roughly the same paragraph, but doesn’t use it as the definition of “object”. Nonetheless, the interpretation is the same. The alternative interpretation – treating [basic.life] as creating an object as soon as suitable storage is obtained – means that you are creating Schrödinger’s objects*, which contradicts N3337 [intro.object]/6:

Two objects that are not bit-fields may have the same address if one
is a subobject of the other, or if at least one is a base class
subobject of zero size and they are of different types; otherwise,
they shall have distinct addresses.


* Storage with the proper alignment and size for a type T is by definition storage with the proper alignment and size for every other type whose size and alignment requirements are equal to or less than those of T. Thus, that interpretation means that obtaining the storage simultaneously creates an infinite set of objects with different types in said storage, all having the same address.

Leave a Comment