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 the object or reference. An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. [ Note: Initialization by a trivial copy/move constructor is non-vacuous initialization. — end note ] The lifetime of an object of type T begins when:
(1.1) storage with the proper alignment and size for type T is obtained, and
(1.2) if the object has non-vacuous initialization, its initialization is complete,
See this code:
alignas(int) char obj[sizeof(int)];
Does basic.life/1 mean that here an
int (and several other types, which has the same or less alignment/size requirements as
int) has begun its lifetime?
What does this even mean? If an object has begun its lifetime, is it created? [intro.object/1] says:
[...] An object is created by a definition ([basic.def]), by a new-expression, when implicitly changing the active member of a union ([class.union]), or when a temporary object is created ([conv.rval], [class.temporary]) [...]
So, according to this, my
obj (as an
int) is not created. But its lifetime as an
int (and as other, possibly infinite-type vacuously-initializable objects) has started.
I'm confused, can you give a clarification on this?
You cannot begin the lifetime of a object unless the object has been created. And [intro.object]/1 defines the only ways in which objects can be created:
An object is created by a definition (6.1), by a new-expression (8.3.4), when implicitly changing the active member of a union (12.3), or when a temporary object is created (7.4, 15.2).
The object created by this definition is of type
char. Therefore, that is the only object whose lifetime begins. And no other objects are created by this construct.
To lend credence to this interpretation, the proposal for C++20 P0593 exists whose primary purpose is to allow that very declaration to implicitly create other such objects.
The condition in (1.2) still bothers me. Why is it there?
It is there because it cannot say "the initialization is complete" for an object that doesn't undergo initialization.
suppose, that I have a
new(obj) intafterwards. That clearly creates an
intobject. But before that,
objhas obtained the necessary storage.
No, the declaration of
obj obtained storage for an object of type
char. What obtains storage for the
int object being created is
new(obj). Yes, the placement-new expression obtains storage for the object that it creates. Just like a declaration of a variable obtains storage for the object it creates.
Just because that storage happens to exist already doesn't mean it isn't being obtained.