'When I perform placement new on trivial object, Is it guaranteed to preserve the object/value representation?
struct A
{
int x;
}
A t{};
t.x = 5;
new (&t) A;
// is it always safe to assume that t.x is 5?
assert(t.x == 5);
As far as I know, when a trivial object of class type is created, the compiler can omit the call of explicit or implicit default constructor because no initialization is required. (is that right?)
Then, If placement new is performed on a trivial object whose lifetime has already begun, is it guaranteed to preserve its object/value representation? (If so, I want to know where I can find the specification..)
Solution 1:[1]
From looking at the Standard, the program has undefined behavior because of an invalid use of an object with indeterminate value.
Per [basic.life]/8, since the object of type A created by the placement new-expression exactly overlays the original object t, using the name t after that point refers to the A object created by the new-expression.
In [basic.indet]/1, we have:
When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]).
One important detail here (which I missed at first) is that "obtaining storage" is different from "allocating storage" or the storage duration of a storage region. The "obtain storage" words are also used to define the beginning of an object's lifetime in [basic.life]/1 and in the context of a new-expression in [expr.new]/10:
A new-expression may obtain storage for the object by calling an allocation function ([basic.stc.dynamic.allocation]). ... [ Note: ... The set of allocation and deallocation functions that may be called by a new-expression may include functions that do not perform allocation or deallocation; for example, see [new.delete.placement]. — end note ]
So the placement new-expression "obtains storage" for the object of type A and its subobject of type int when it calls operator new(void*). For this purpose, it doesn't make a difference that the memory locations in the storage region actually have static storage duration. Since "no initialization is performed" for the created subobject of type int with dynamic storage duration, it has an indeterminate value.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | aschepler |
