2

This question rises for a discussion of the answer to another question about allocation in constexpr context.

cppreference states that std::allocator<T>::allocate(std::size_t n) allocates an array of n T but does not start the lifetime of the actual T objects.

Thus, pointer arithmetic is well defined but cppreference states that accessing the objects before there construction is undefined behavior, which is not mandate in the standard.

For objects of non implicit lifetime type, it does not been to be mandated: objects that don't exist can't be accessed basic.life#6 (thanks to Ben Voigt for the reference).

But what about objects of an implicit lifetime type? The standard says that the storage is created from ::operator new, which implicitly creates objects.

So, in this case, does both the array and the sub-objects are in their lifetime?

More generally, are sub-objects of implicit lifetime types also implicitly created when the containing object is implicitly created?

Here is a snippet to illustrate the problem:

static constexpr std::size_t N = 100;
using Type_t = int;
void process() {
    auto allocator = std::allocator<std::array<Type_t, N>>{};
    auto ptr = allocator.allocate(1);
    // ptr is the address of a std::array<Type_t, N>[1]
    Type_t* it = ptr->data();
    // accessing the data of the std::array<Type_t, N>:
    // is it in its lifetime?
    // starting the lifetime of the array's elements
    for (std::size_t i = 0; i != N; ++i) {
        std::construct_at(it, static_cast<Type_t>(i * i));
        ++it;
    }
    allocator.deallocate(ptr, 1);
}

LIVE

Has the (single) std::array in the storage created by allocate(1) implicitly started its lifetime?

7
  • 1
    Don't confuse the name "objects" in the standard as being similar to instance of "classes". If you have an array of chars, the subobjects are chars. Commented Nov 6 at 14:34
  • @PepijnKramer adited: replacing "class" by "type" Commented Nov 6 at 14:38
  • undefined behavior for most access to objects which have been allocated but before their lifetime begins is indeed specified in the Standard: basic.life/6 Commented Nov 6 at 18:21
  • 3
    Note that operations as operator new do not implicitly create objects by themselves. They implicitly create objects only if doing so would result in the program having defined behavior. "So, in this case, does both the array and the sub-objects are in their lifetime?" In which case? You don't show any code. If you just call allocate, the underlying operator new does not implicitly create any objects. It depends on what is then performed in the program. Commented Nov 6 at 18:39
  • In practice, even if you don't need to explicitly start the lifetime of the object, I still would. If it isn't necessary the compiler should remove the code for you, it protects you against changes to the type that would make it non-trivial and it avoids anyone else from questioning whether the code is valid or not. Ex. godbolt.org/z/GE61xEvr5 Commented Nov 6 at 19:07

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.