3 回答

TA貢獻1813條經驗 獲得超2個贊
128位整數類型僅在64位目標上可用,因此即使您已經檢測到最新的GCC版本,也需要檢查可用性。從理論上講,gcc 可以在需要4個32位寄存器來保存一個寄存器的機器上支持TImode整數,但是我認為在任何情況下它都不支持。
GCC 4.6及更高版本具有__int128/ unsigned __int128定義為內置類型。 使用
#ifdef __SIZEOF_INT128__檢測到它。
GCC 4.1及更高版本在__int128_t和__uint128_t中定義<stdint.h>。在最新的編譯器上,這大概是用定義的__int128。(#include <stdint.h>如果要使用__int128_t名稱代替,則仍然需要__int128。)
我在Godbolt編譯器資源管理器上測試了第一個支持這3種功能的編譯器版本(在x86-64上)。Godbolt僅返回到gcc4.1,ICC13和clang3.0,因此我用<= 4.1表示實際的第一個支持可能更早。
legacy recommended(?) | One way of detecting support
__uint128_t | [unsigned] __int128 | #ifdef __SIZEOF_INT128__
gcc <= 4.1 | 4.6 | 4.6
clang <= 3.0 | 3.1 | 3.3
ICC <= 13 | <= 13 | 16. (Godbolt doesn't have 14 or 15)
如果您為ARM或x86之類的32位體系結構進行編譯-m32,即使這些編譯器中的任何最新版本都不支持128位整數類型。 因此,如果沒有它,代碼完全可以工作,則需要在使用前檢測支持。
我知道唯一可以檢測到的直接CPP宏是__SIZEOF_INT128__,但是不幸的是,一些舊的編譯器版本在不定義它的情況下就支持它。(并且沒有__uint128_tgcc4.6樣式的宏unsigned __int128)。 如何知道__uint128_t是否已定義
某些人仍然使用RHEL(RedHat Enterprise Linux)上的gcc4.4之類的古老編譯器版本,或類似的硬殼舊系統。如果您關心這樣的過時gcc版本,則可能要堅持使用__uint128_t。也許sizeof(int_fast32_t)出于某種原因,在某些64位ISA上可以檢測到64 位的錯誤。但不是在x32或ILP32 AArch64之類的ILP32 ISA上,因此也許只是檢查sizeof(void*)是否__SIZEOF_INT128__未定義。
gcc __int128可能沒有定義一些64位ISA,甚至gcc 卻定義了一些32位ISA __int128,但我不知道。
正如這里對另一個答案的評論所指出的那樣,GCC內部是整數TI模式。(四整數=的4x寬度int,DImode =兩倍的寬度,SImode =普通的int。)正如GCC手冊指出的那樣,__int128支持128位整數模式(TImode)的目標支持。
typedef unsigned uint128_t __attribute__ ((mode (TI)));
隨機事實:ICC19 -E -dM定義:
#define __GLIBCXX_TYPE_INT_N_0 __int128
#define __GLIBCXX_BITSIZE_INT_N_0 128
測試功能為:
#include <stdint.h>
#define uint128_t __uint128_t
//#define uint128_t unsigned __int128
uint128_t mul64(uint64_t a, uint64_t b) {
return (uint128_t)a * b;
}
所有支持它的編譯器都可以高效地對其進行編譯,從而
mov rax, rdi
mul rsi
ret # return in RDX:RAX

TA貢獻1797條經驗 獲得超6個贊
啊,大整數不是C的強項。
GCC確實有一個unsigned __int128
/ __int128
類型,從版本4.something開始(此處不確定)。我似乎確實記得,但是,__int128_t
在此之前有一個定義。
這些僅在64位目標上可用。
(編者注:這個答案用來聲稱GCC定義uint128_t
和int128_t
我在Godbolt編譯探險測試的版本中沒有定義這些類型,而領先的。__
從gcc4.1到8.2,或鏗鏘或ICC)。
- 3 回答
- 0 關注
- 2254 瀏覽
添加回答
舉報