gcc用long而不是__int128实例化模板

gcc instantiates template with long instead of __int128

本文关键字:int128 实例化 long gcc      更新时间:2023-10-16

我感到茫然和困惑。对我的big模板的第二次调用中发生了什么?

template <class T> void big(T t) {  }
int main()
{
    big(9223372036854775808);                        // calls big<__int128>
    big(941832094813209483120);                      // calls big<long>
    big(239120938091238093219203810293801923832019); // calls big<__int128>
}

为什么为941832094813209483120实例化了一个长模板,而其他两个值得到了一个__int128模板

这个值显然不适合long,并且似乎会导致溢出(请参阅下面的完整gdb会话):

big<long> (t=1048147054022350704) at blob.cpp:1

我在gcc-5.2.0gcc-4.9.2中都观察到了这一点,同时我使用gdb-7.7.1进行调试。

这是我完整的gdb会话:

Breakpoint 1, main () at blob.cpp:5
(gdb) s 
big<__int128> (t=0x00000000000000008000000000000000) at blob.cpp:1
(gdb)  
main () at blob.cpp:6
(gdb)  
big<long> (t=1048147054022350704) at blob.cpp:1
(gdb)  
main () at blob.cpp:7
(gdb)  
big<__int128> (t=0x0000000000000000d90567828f8ae8d3) at blob.cpp:1
(gdb)

由于OP已经确认long-long在他们的系统上是64位的,我们可以看到128位Integers上的gcc文档说:

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

因此,虽然我同意这种行为很奇怪,但从技术上讲,它不是一个bug,因为gcc不支持这种场景,并明确记录了这种情况。

编译器可能支持C++11标准草案3.9.1:中的扩展有符号整数

也可能存在实现定义的扩展有符号整数类型

但它们是实现定义的,第2.14.2节中整数文字的措辞是:

如果整数文本不能由其列表中的任何类型表示,则扩展整数类型(3.9.1)可以表示其值,则可能具有扩展整数类型[…]

强调可能