![](/img/trans.png)
[英]reinterpret_cast unsigned char* as uint64_t* - is this UB?
[英]reinterpret_cast of __uint128_t
據我所知, reinterpret_cast 一定不會導致數據丟失。
因此,由於 integer 小於指針,因此無法在 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 位 integer 不是整數類型,但至少 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)都在謊稱自己是“最大值”。
但
在 -std=gnu++XX 模式下,libstdc++ 使 is_integral_v<__int128> 變為真
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.