根据reinterpret_cast
page on cppreference.com , 有 11 次转化
can be done with
reinterpret_cast
, except when such conversions would cast away constness or volatility.
所以,我的问题是:是否可以编写一个像这样的 constexpr 函数
template <typename T1, typename T2>
constexpr bool is_reinterpret_cast_safe() {
// ...
}
根据这 11 个点检查是否允许转换?由于 GCC 和 Clang 等编译器能够检查代码是否违反了严格的别名规则,使用 -fstrict-aliasing -Wstrict-aliasing
进行编译,我认为这应该是可行的。
我知道 C++20 引入了 std::bit_cast
, 但它仍然不受任何编译器的支持。在编译时在两个转换函数之间进行选择可能很有用
template <typename T1, typename T2>
T1 f_reinterpret_cast(T2 d) {
static_assert(sizeof(T1) == sizeof(T2));
return *reinterpret_cast<T1*>(&d); // could be undefined behavior;
}
template <typename T1, typename T2>
T1 f_memcpy(T2 d) {
static_assert(sizeof(T1) == sizeof(T2));
T1 n;
std::memcpy(&n, &d, sizeof(T2)); // OK
return n;
}
使用 SFINAE 或 if constexpr
:
template <typename T1, typename T2>
T1 conv(T2 d) {
if constexpr (is_reinterpret_cast_safe<T1, T2>())
return conv_reinterpret_cast<T1, T2>(d);
else
return conv_memcpy<T1, T2>(d);
}
您可以在 https://godbolt.org/z/Ex6GnP 上找到代码.
最佳答案
编译器在编译时检查reinterpret_cast 表达式 的有效性:访问对象时会违反别名规则:
int i = 0; //OK
double j* = reinterpret_cast <double*> (i); //OK
double k = *j; //strict aliasing violation
无法检查 reinterpret_cast
不会导致指针无法用于访问它指向的对象。
关于c++ - 确定 reinterpret_cast 在编译时是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62929842/