One of the preconditions on std::launder
requires that object is within its lifetime. I assume that it is a necessary condition for being able to dereference the element. Does it mean, that if I obtain a pointer to to an array element, then no launder is needed, if I perform only arithmetic? Or it is just UB?
A clarifying code example. Some remarks clarifying the question are made within the comments to the code.
alignas(T) std::byte memory[3 * sizeof(T)]; // implicitly creates an array of 3 T
// elements on the stack
auto arr_ptr = std::launder(reinterpret_cast<T(*)[3]>(memory));
// Now we have an implictly created array of 3 T, but unless T is an
// implicit-lifetime type, no element has began its lifetime yet
auto ptr1 = reinterpet_cast<T*>(memory); // points to the storage occupied by the
// first element of T
// is arithmetic on ptr1 valid? Or it is treated as regular conversion between
// types that are not pointer interconvertible, and since no T element exists
// there, arithmetic is UB by the standard.
// Or, since the address is of an valid element of array of T
// (storage address is the same, and we do not // dereference it), everything is
// okay?
auto ptr2 = std::launder(reinterpret_cast<T*>(memory));
// does not point to an object within its lifetime, UB, therefore, it can not be
// used for pointer arithmetic.