128位整数类型是only ever available on 64-bit targets,所以即使您已经检测到最新的GCC版本,也需要判断可用性.理论上,gcc could在需要4个32位寄存器才能保存的机器上支持TImode整数,但我认为在任何情况下都不支持.
GCC 4.6 and later has a __int128
/ unsigned __int128
defined as a built-in type. Use
#ifdef __SIZEOF_INT128__
to detect it.
GCC 4.1 and later define 101 and 102 as built-in types.(这些也不需要#include <stdint.h>
元.证据on Godbolt.)
I tested on the Godbolt compiler explorer for the first versions of compilers to support each of these 3 things (on x86-64). Godbolt only goes back to gcc4.1, ICC13, and clang3.0, so I've used <= 4.1 to indicate that the actual first support might have been even earlier.
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)
If you compile for a 32-bit architecture like ARM, or x86 with 100, no 128-bit integer type is supported with even the newest version of any of these compilers.,因此您需要在使用之前检测支持,如果您的代码在没有支持的情况下也可以工作的话.
据我所知,检测它的唯一直接CPP宏是__SIZEOF_INT128__
,但不幸的是,一些旧的编译器版本在没有定义它的情况下支持它.(__uint128_t
没有宏,只有gcc4.6样式unsigned __int128
).How to know if __uint128_t is defined
有些人仍然使用古老的编译器版本,比如gcc4.4在RHEL(RedHat Enterprise Linux)或类似的老旧系统上.如果你关心像这样过时的gcc版本,你可能想坚持使用__uint128_t
.可能会检测sizeof(void*) == 8
的64位,作为__SIZEOF_INT128__
未定义的回退.(我认为GNU系统总是有CHAR_BIT==8
个).这将导致64位ISA(如x86-64 Linux x32或AArch64 ILP32)上的ILP32 ABI出现假阴性,但对于使用不定义__SIZEOF_INT128__
的旧编译器的人来说,这已经只是一个退步/额外的好处.
可能有一些64位的ISA,GCC没有定义__int128
,或者甚至有一些32位的ISA,GCC定义了__int128
,但我不知道有什么.
正如对另一个答案的 comments 所指出的,GCC内部是整数TI模式.(Tetra integer=int
的4x宽度,vs.DImode=双倍宽度vs.SImode=普通int
.)As the GCC manual points out、__int128
在支持128位整数模式(TImode)的目标上受支持.
// __uint128_t is pre-defined equivalently to this
typedef unsigned uint128 __attribute__ ((mode (TI)));
随机事实:ICC19和g++/clang++-E -dM
定义:
#define __GLIBCXX_TYPE_INT_N_0 __int128
#define __GLIBCXX_BITSIZE_INT_N_0 128
@MarcGlisse comments that's the way you tell libstdc++ to handle extra integer types (overload abs, specialize type traits, etc)
icpc
定义了即使是-xc
(编译为C,而不是C++),而G++-XC和CLAN++XC不这样.但是编译实际icc
(例如, Select C++而不是C++中的GOOBED下拉)不定义这个宏.
测试功能为:
#include <stdint.h> // for uint64_t
#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 which mul uses implicitly