当我尝试在gcc 4.9.1中分配一个128位整数时,我得到一个warning: integer constant is too large for its type
。
示例代码
int main(void) {
__uint128_t p = 47942806932686753431;
return 0;
}
输出
我用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;
^
是我做错了什么,还是gcc中的一个bug?
4条答案
按热度按时间9ceoxa921#
是我做错了什么,还是gcc中的一个bug?
问题出在
47942806932686753431
部分,而不是__uint128_t p
。根据gcc docs,没有办法声明128位常量:GCC不支持为long long整数小于128位宽的目标表示__int128类型的整数常量。
所以,看起来虽然你可以有128位 * 变量 *,但你不能有128位 * 常量 *,除非你的
long long
是128位宽的。解决方法可以是使用基本的算术运算从“较窄”的整数常量构造128位值,并希望编译器执行constant folding。
eoigrqb62#
你试过这个吗?
编辑11月25日
很抱歉在上一篇文章中的错误解释。说真的,我没有把这个答案当作笑话。虽然GCC文档指出没有办法表示128位整数常量,但这篇文章只是为那些想要轻松地为__uint128_t变量赋值的人提供了一个 * 解决方案 *。
您可以尝试使用GCC(7.2.0)或Clang(5.0.0)编译下面的代码。它打印所需的结果。
stdout:
这只是一种 * 解决方法 *,因为它通过将“值”放在.rodata部分(如果你objdump它)来玩弄指针,而且它不是可移植的(x86_64和aarch64可以,但arm和x86不行)。我认为这对那些在桌面机器上编码的人来说已经足够了。
lp0sw83n3#
我也遇到了同样的问题,于是我想出了一个使用用户定义文字的解决方案。下面是如何示例化用户定义的literal _xxl:
输出:
下面是用户定义的literal _xxl的实现
它可以在constexpr中使用,就像普通的整数常量一样:
ioekq8ef4#
我建议使用一个简单的宏来合并两个64位值:
示例用法:
或者,您可以将0x前缀移动到宏中(不建议):
因此,您可以使用稍短的
UINT128(0102030405060708, 090a0b0c0d0e0f10)
,但这可能会混淆语法突出显示,因为0102030405060708
可能会被误解为八进制常量,而090a0b0c0d0e0f10
本身并不是一个有效的标记,这就是为什么我不推荐这样做。