c++initializationlanguage-lawyerobject-lifetime

Is it really possible to separate storage allocation from object initialization?


From [basic.life/1]:

The lifetime of an object or reference is a runtime property of the object or reference. A variable is said to have vacuous initialization if it is default-initialized and, if it is of class type or a (possibly multi-dimensional) array thereof, that class type has a trivial default constructor. The lifetime of an object of type T begins when:

  • storage with the proper alignment and size for type T is obtained, and
  • its initialization (if any) is complete (including vacuous initialization) ([dcl.init]),

except that if the object is a union member or subobject thereof, its lifetime only begins if that union member is the initialized member in the union ([dcl.init.aggr], [class.base.init]), or as described in [class.union] and [class.copy.ctor], and except as described in [allocator.members].

From [dcl.init.general/1]:

If no initializer is specified for an object, the object is default-initialized.

From [basic.indet/1]:

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]). [Note 1: Objects with static or thread storage duration are zero-initialized, see [basic.start.static]. — end note]

Consider this C++ program:

int main() {
    int i;
    i = 3;
    return 0;
}

Is initialization performed in the first statement int i; or second statement i = 3; of the function main according to the C++ standard?

I think it is the former, which performs vacuous initialization to an indeterminate value and therefore begins the lifetime of the object (the latter does not perform initialization, it performs assignment to the value 3). If that is so, is it really possible to separate storage allocation from object initialization?


Solution

  • If that is so, is it really possible to separate storage allocation from object initialization?

    Yes:

    void *ptr = malloc(sizeof(int));
    

    ptr points to allocated storage, but no objects live in that storage (C++20 says that some objects may be there, but nevermind that now). Objects won't exist unless we create some there:

    new(ptr) int;