Current draft standard says (previous standards have similar wording) in [basic.life/1]:
The lifetime of an object or reference is a runtime property of
Because the Standard deliberately refrains from requiring that all implementations be suitable for all purposes, it will often be necessary for quality implementations intended for various purposes to guarantee the behavior of code over which the Standard itself would impose no requirements.
If some type T
supports implicit object creation and a program converts the address of some object to a T*
, a high-quality implementation which is intended to support low-level programming concepts without requiring special syntax will behave as though such conversion creates an object of type T
in cases where that would allow the program to have defined behavior, but would not implicitly create such objects is cases where doing so would not be necessary but would instead result in Undefined Behavior by destroying other objects.
Thus, if float
and uint32_t
are the same size and have the same alignment requirements, then given e.g.
alignas(uint32_t) char obj[sizeof(uint32_t)];
float *fp = (float*)obj;
*fp = 1.0f;
uint32_t *up = (uint32_t*)obj;
The initialization of fp
would create a float
because that would be needed to make the assignment to *fp
work. If up
will be used in a fashion that would require a uint32_t
to exist there, the assignment to up
could create one while destroying the float
that was there. If up
isn't used in such a fashion, but fp
is used in a way that would require that the float
still exist, that float
would still exist. If both pointers are used in ways that would require that the respective objects still exist, even a quality compiler intended for low-level programming might be incapable of handling that possibility.
Note that implementations which are not particularly suitable for low-level programming may not support the semantics described here. The authors of the Standard allows compiler writers to support such semantics or not, based upon whether they are necessary for their compilers' intended purposes; unfortunately, there is not as yet any standard way to distinguish compilers that are suitable for such purposes from those that aren't.