c++ - 重新解释 __uint128_t
问题描述
据我所知, reinterpret_cast 一定不会导致数据丢失。
所以不可能在 X86_64 中编译这样的代码,因为整数小于指针
#include <cstdio>
int main() {
int a = 123;
int res = reinterpret_cast<int>(reinterpret_cast<void*>(a));
printf("%d", a == res);
}
问题是:为什么我可以在 GCC 和 Clang 中编译这样的代码?
#include <cstdio>
int main() {
__uint128_t a = 4000000000000000000;
a *= 100;
__uint128_t res = reinterpret_cast<__uint128_t>(reinterpret_cast<void*>(a));
printf("%d", a == res);
}
我得到的结果是“0”,表示有数据丢失。
编辑
我认为它可能有 3 种可能的变体。编译器错误、规范滥用或规范后果。这是哪一个?
解决方案
这里解释了https://en.cppreference.com/w/cpp/language/reinterpret_cast
- 指针可以转换为任何大到足以容纳其类型的所有值的整数类型(例如到 std::uintptr_t)
这就是为什么您对第一种情况有错误的原因
- 任何整数或枚举类型的值都可以转换为指针类型...
这就是为什么你没有错误,但在第二种情况下它会包装为 0。它以某种方式假设指针类型与任何整数类型相比具有最大的范围,而对于 128 位整数,情况并非如此。
请注意,一般来说 128 位整数不是整数类型,但至少 gcc 将其定义为 gcc 扩展中的原样:
来自https://quuxplusone.github.io/blog/2019/02/28/is-int128-integral/
libstdc++(在标准、非 gnu++XX 模式下)将 is_integral_v<__int128> 保留为 false。从库实现者的角度来看,这有一定的意义,因为 __int128 不是标准整数类型之一,而且,如果你称它为整数,那么你必须面对 intmax_t (即 64 位每个重要的 ABI)都在谎称自己是“最大值”。</p>
但
在 -std=gnu++XX 模式下,libstdc++ 使 is_integral_v<__int128> 变为真
推荐阅读
- c++ - Cannot print out decimal numbers upto 6 in a void function.the value are correct checked by debugging.the problem is with the output
- token - 星云认证注销
- java - 像导航抽屉一样切换片段(带后退箭头)
- c++ - C++ - 如何遍历数组的所有组合以进行暴力破解
- python - /blog/addblog 处的 ValueError
- dictionary - 传单:如何在鼠标悬停在该标记上时仅突出显示位于标记后面的多边形?
- android - 安卓机房:自动查询代码不校验完整性
- json - 在颤动中使用 Chopper 库将 JSON 响应转换为模型对象?
- php - 如何在 MacOS catalina、Xampp VM 和 php7.3 中安装 php_gmp
- serialization - Rust bincode enum 二进制序列化