[Base] Add aliasing-safe xe::memory::Reinterpret
Accessing the same memory as different types (other than char) using reinterpret_cast or a union is undefined behavior that has already caused issues like #1971. Also adds a XE_RESTRICT_VAR definition for declaring non-aliasing pointers in performance-critical areas in the future.
This commit is contained in:
parent
a90f83d44c
commit
f0ad4f4587
|
@ -16,6 +16,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/byte_order.h"
|
#include "xenia/base/byte_order.h"
|
||||||
|
@ -24,6 +25,30 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace memory {
|
namespace memory {
|
||||||
|
|
||||||
|
// For variable declarations (not return values or `this` pointer).
|
||||||
|
// Not propagated.
|
||||||
|
#define XE_RESTRICT_VAR __restrict
|
||||||
|
|
||||||
|
// Aliasing-safe bit reinterpretation.
|
||||||
|
// For more complex cases such as non-trivially-copyable types, write copying
|
||||||
|
// code respecting the requirements for them externally instead of using these
|
||||||
|
// functions.
|
||||||
|
|
||||||
|
template <typename Dst, typename Src>
|
||||||
|
void Reinterpret(Dst& XE_RESTRICT_VAR dst, const Src& XE_RESTRICT_VAR src) {
|
||||||
|
static_assert(sizeof(Dst) == sizeof(Src));
|
||||||
|
static_assert(std::is_trivially_copyable_v<Dst>);
|
||||||
|
static_assert(std::is_trivially_copyable_v<Src>);
|
||||||
|
std::memcpy(&dst, &src, sizeof(Dst));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Dst, typename Src>
|
||||||
|
Dst Reinterpret(const Src& XE_RESTRICT_VAR src) {
|
||||||
|
Dst dst;
|
||||||
|
Reinterpret(dst, src);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
#if XE_PLATFORM_ANDROID
|
#if XE_PLATFORM_ANDROID
|
||||||
void AndroidInitialize();
|
void AndroidInitialize();
|
||||||
void AndroidShutdown();
|
void AndroidShutdown();
|
||||||
|
|
Loading…
Reference in New Issue