According to [intro.object]/10:
Some operations are described as implicitly creating objects within a specified region of storage. For each operation that is specified as implicitly creating objects, that operation implicitly creates and starts the lifetime of zero or more objects of implicit-lifetime types ([basic.types.general]) in its specified region of storage if doing so would result in the program having defined behavior. If no such set of objects would give the program defined behavior, the behavior of the program is undefined. If multiple such sets of objects would give the program defined behavior, it is unspecified which such set of objects is created.
it can choose not to create objects if that would make the program legal.
Consider the following code (from this question):
void* p = operator new(1);
new (p) char;
delete static_cast<char*>(p);
operator new implicitly creates objects, according to [intro.object]/13:
Any implicit or explicit invocation of a function named operator new or operator new[] implicitly creates objects in the returned region of storage and returns a pointer to a suitable created object.
It also follows [intro.object]/10, so consider two options:
- Implicitly creates a
charobject. See this answer. - Does not create a
charobject. First,ppoints to uninitialized memory allocated byoperator new. Then, explicitly create acharobject on it by placement new. Finally, it is used on delete-expression.
The question is whether option 2 is legal, that is, whether p automatically points to the object created by placement new.
The standard rules at [basic.life]/8:
If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if the original object is transparently replaceable (see below) by the new object.
But no object occupies the memory pointed to by p. Therefore, no replacement takes place, [basic.life]/8 doesn't apply in this case.
I didn't find a stipulation in the standard. So, does the standard allow option 2?
struct s {int a;};, the implicitly created objects will be thesitself and itsintmember, the set {s object , int object} is created. From a formal standpoint, the empty set {} is permissible, but can only be created when it gives well defined results.