在C中分配128位整数

ibl*_*lue 19 c gcc

当我尝试在gcc 4.9.1中分配128位整数时,我得到一个warning: integer constant is too large for its type.

示例代码

int main(void) {
  __uint128_t p = 47942806932686753431;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量

我正在编译,gcc -std=c11 -o test test.c我得到:

test.c: In function ‘main’:
test.c:2:19: warning: integer constant is too large for its type
   __uint128_t p = 47942806932686753431;
               ^
Run Code Online (Sandbox Code Playgroud)

我做错了什么或者这是gcc中的错误?

el.*_*ado 28

我做错了什么或者这是gcc中的错误?

问题47942806932686753431部分在于,而不是在__uint128_t p.根据gcc docs,没有办法声明128位常量:

GCC中不支持为长整数小于128位宽的目标表达__int128类型的整数常量.

所以,看起来虽然你可以拥有128位变量,但你不能拥有128位常数,除非你long long是128位宽.

解决方法可能是使用基本算术运算从"较窄"积分常量构造128位值,并希望编译器执行常量折叠.

  • 也许"不能有128位整数常量,除非你的`intmax_t`至少是128位宽"? (2认同)
  • @ el.pescado,虽然没有直接支持,但你仍然可以拥有该类型的常量表达式.例如`((__ int128_t)1000000000000*HIGH)+ LOW`可以是一种为大值构造这种表达式的方法,其中"HIGH"和"LOW"是数字的高位和低位. (2认同)

小智 9

你试过这个吗?

__int128 p = *(__int128*) "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
Run Code Online (Sandbox Code Playgroud)

11 月 25 日编辑

对于上一篇文章的澄清不充分,我们深表歉意。说实话,我发布这个答案并不是为了开玩笑。尽管 GCC 文档指出无法表达 128 位整数常量,但这篇文章只是为那些想要轻松为 __uint128_t 变量赋值的人提供了一种解决方法。

您可以尝试使用 GCC (7.2.0) 或 Clang (5.0.0) 编译下面的代码。它打印所需的结果。

#include <stdint.h>
#include <stdio.h>

int main()
{
    __uint128_t p = *(__int128*) "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
    printf("HIGH %016llx\n", (uint64_t) (p >> 64));
    printf("LOW  %016llx\n", (uint64_t) p);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

标准输出:

HIGH 0f0e0d0c0b0a0908
LOW  0706050403020100
Run Code Online (Sandbox Code Playgroud)

这仅被视为一种解决方法,因为它通过将“值”放置在 .rodata 部分(如果您对其进行 objdump)来对指针进行欺骗,并且它不可移植(x86_64 和 aarch64 很好,但不是 arm 和 x86)。我认为对于那些在台式机上编码的人来说已经足够了。

  • 即使假设字符串值对于任何需要的字节顺序都是正确的,对于任何对“__int128”变量有对齐限制的体系结构来说,这可能会导致“SIGBUS”。 (7认同)
  • 这是故意开玩笑吗? (3认同)
  • 除了对齐之外,这个答案中的解决方案还存在严格别名的问题,但是像 `__uint128_t q = (union { unsigned char r[16]; __uint128_t i; }) {00,01,02,03,04,05 ,06,07,8,9,0xa,0xb,0xc,0xd,0xe,0xf}.i;` 有效。它假定“char”的字节序和宽度为 8 位,但此评论上方的答案也是如此。 (2认同)