melquiades
melquiades

Reputation: 19

gcc 7.3 128-bit unsigned integer operation

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

Answers (2)

phuclv
phuclv

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 with long long integer less than 128 bits wide.

128-bit Integers

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;
      |                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Demo on Godbolt

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.

integer constant

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

chux
chux

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

Related Questions