What does it mean to obtain storage?

Viewed 178

[basic.indet] p1 says:

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.

What exactly does it mean for storage to be acquired for an object? Consider this code snippet:

int a = 0;
new (&a) int;

When is the storage for the int object created by the new-expression acquired? Is it when the storage for the original object that was created by definition was acquired, or would it be acquired when the object is created by the new-expression?

(Side note: According to P0593 this new object will have an indeterminate value due to [basic.life] p4, however, this is not explicitly specified, unless storage is considered to be acquired when the second object is created)

Edit: This seems to be the subject of a unanswered defect report CWG 1997

2 Answers

The storage is initially allocated for the automatic object. The placement-new then reuses that storage for the dynamic object.

The standard doesn't appear to define the meaning of the word "obtain" in relation to allocation and reusage. If it was restricted to mean the same as "allocate", then it would be a redundant term, so it is reasonable to asssume that it covers both allocation, and reusage.

Under this interpretation, the storage would have been obtained at the placement new expression. And indeed, the value would be indeterminate. There is a trick to keep the value:

int a = 0;
int orig = a;
new (&a) int(orig);

A decent optimising compiler can see that the copies are redundant. For arrays, same can be achieved with memcpy, and those can be optimised away too as long as the length is constant.

Actually, it's quite simple. From [expr.new]/8:

A new-expression may obtain storage for the object by calling an allocation function

Placement-new is an allocation function. It may only return the same pointer it was given, but this process is still considered "obtaining storage for the object". That storage being the storage pointed to by &a. And therefore, it works exactly as expected. The storage currently in use by a is being reused. So the current a ends its lifetime, and a new int begins its lifetime in the same storage.

"Obtain storage for an object" doesn't mean "make storage appear that wasn't there before". It means exactly what it says: to get a piece of storage for the purpose of putting an object there. This is different from simply getting a piece of storage. That the piece of storage may already be in use by some other object is orthogonal.

Related