Reputation: 19
I'm confused with the usage of 128-bit integer. Please look at the test code:
uint128_t test_data = 0x00000000FFFFFFFF0101010101010101;
uint64_t test_data_h = test_data >> 64;
uint64_t test_data_l = test_data ;
printf("test_data 0x %016llx %016llx\n", test_data_h, test_data_l);
I expect the test_data_h
to be 0x00000000FFFFFFFF, but the result is :
test data 0x 0000000000000000 0101010101010101
Why is this?
Upvotes: 1
Views: 640
Reputation: 41753
GCC doesn't support 128-bit integer literal
There is no support in GCC for expressing an integer constant of type
__int128
for targets withlong long
integer less than 128 bits wide.
So you'll have to construct it from smaller parts ((unsigned __int128)high << 64) | low
If you turned on all warnings you'll see
<source>:6:35: warning: integer constant is too large for its type
6 | unsigned __int128 test_data = 0x00000000FFFFFFFF0101010101010101;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because the type of an integer literal is “the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix
was used” and the list of types doesn't contain non-standard types like __int128
.
C99 also supports “extended integer types” and in the same page you can also see that
If the value of the integer constant is too big to fit in any of the types allowed by suffix/base combination and the compiler supports extended integer types (such as
__int128
), the constant may be given the extended integer type; otherwise, the program is ill-formed.
Unfortunately __int128
is not an extended integer type in GCC. You can easily see that intmax_t
maps to long long
instead of __int128
. Therefore you can't have __int128
literal, unless the compiler has another extension, like ICC. You can see that there's no relevant integer literal warning from ICC in the Godbolt link above
Upvotes: 2
Reputation: 153303
Many compilers do not support 128 bit constants.
Instead
// uint128_t test_data = 0x00000000FFFFFFFF0101010101010101;
uint128_t test_data = (((uint128_t) 0x00000000FFFFFFFF) << 64) | 0x0101010101010101;
Tip: enable all compiler warnings.
Upvotes: 3