The current draft standard (and presumably C++17) say in [basic.compound/4]:
[ Note: An array object and its first element are not pointer-interconvertible, even though they have the same address. — end note ]
So a pointer to an object cannot be reinterpret_cast
'd to get its enclosing array pointer.
Now, there is std::launder
, [ptr.launder/1]:
template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept
;Requires:
p
represents the address A of a byte in memory. An object X that is within its lifetime and whose type is similar to T is located at the address A. All bytes of storage that would be reachable through the result are reachable throughp
(see below).
And the definion of reachable is in [ptr.launder/3]:
Remarks: An invocation of this function may be used in a core constant expression whenever the value of its argument may be used in a core constant expression. A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y, an object that is pointer-interconvertible with Y, or the immediately-enclosing array object if Y is an array element. The program is ill-formed if T is a function type or cv void.
Now, at first sight, it seems that std::launder
is can be used to do the aforementioned conversion, because of the part I've put emphasis.
But. If p
points to an object of an array, the bytes of the array is reachable according to this definition (even though p
is not pointer-interconvertible to array-pointer), just like the result of the launder. So, it seems that the definition doesn't say anything about this issue.
So, can std::launder
be used to convert an object pointer to its enclosing array pointer?