ARTICLE AD BOX
This question is a follow up of Making the non-trivial creation of an array constexpr and Accessing objects of implicit lifetime type in the storage provided by std::allocator, before any explicit construction where I was looking for a way to create a constexpr array of not default-constructible types.
The solution, hinted by the answer of the first question, is to use std::allocator::allocate, which is constexpr.
The second question deals with the fact that this function does not create objects but arrays of objects. Yet I concluded when creating arrays of std::array, the latest were implicitly created as being implicit lifetime type subobjects of implicit lifetime type object (the array of std::array)
But testing it, the code is rejected by clang.
I could reduce the issue to this mre:
#include <array> #include <cstddef> #include <iostream> #include <memory> template <typename T, std::size_t N> constexpr T test() { std::allocator<std::array<T, N>> allocator{}; auto* ptr = allocator.allocate(1); ptr->data()[3] = T{42}; // clang disapprove auto ret = ptr->data()[3]; allocator.deallocate(ptr,1); return ret; } int main() { constexpr std::size_t N = 50000; [[maybe_unused]] constexpr auto val = test<int, N>(); }LIVE
clang reject the constant evaluation, saying that the std::array is not in its lifetime:
note: member call on object outside its lifetime is not allowed in a constant expression 10 | ptr->data()[3] = T{42};
gcc and msvc are fine with this code.
Is this a clang bug or is my assertion that the std::array is created wrong?
4,87811 silver badges38 bronze badges
