I'm worried if my implementation is unsafe or could be improved. Suppose I have an array of bytes (more specifically, std::byte
); is casting an element's address to a void pointer and then to any datatype safe?
template <typename To>
constexpr To *byte_cast(std::byte &From) {
return static_cast<To *>(static_cast<void *>(&From));
}
// or rather
template <typename To>
constexpr To *byte_cast(std::byte *From) {
return static_cast<To *>(static_cast<void *>(From));
}
I'm avoiding reinterpret_cast
due to its unreliability. Do note that I want to the T *
to keep same address of the byte it was cast from.
I do have in mind that the array might not fit the datatype, or maybe endianness might cause a problem, but both will be fixed after my question's answered.
CodePudding user response:
Your paired static_cast
s are exactly equivalent to a reinterpret_cast
. Both cause UB due to strict aliasing violations (except when the target type is char
, unsigned char
, or std::byte
).
The solution is std::bitcast<T>(source)
. It has the interface similar to what you attempted, except that it returns by value. It's not possible to have a "safe reinterpret_cast
" that would return a pointer/reference.
A less modern alternative is std::memcpy
.