C++ gcc用long而不是_int128实例化模板

C++ gcc用long而不是_int128实例化模板,c++,c++11,gcc,gdb,C++,C++11,Gcc,Gdb,我感到茫然和困惑。在对我的big模板的第二次调用中发生了什么 template <class T> void big(T t) { } int main() { big(9223372036854775808); // calls big<__int128> big(941832094813209483120); // calls big<long>

我感到茫然和困惑。在对我的
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>
}
我用
gcc-5.2.0
gcc-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)
blob.cpp处的断点1,main():5 (gdb)s blob处的大(t=0x00000000000000000000000000000000000000000)。cpp:1 (gdb) main()位于blob.cpp:6 (gdb) 大(t=1048147054022350704)在水滴处。cpp:1 (gdb) main()位于blob.cpp:7 (gdb) blob处的大(t=0x0000000000000000d90567828f8ae8d3)。cpp:1 (gdb)
因为OP已经确认long long在他们的系统上是64位的,所以我们可以看到:

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

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

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

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

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

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


重点放在may上。

假设平台上的long-long不是128位,那么GCC中不支持为long-long-integer宽度小于128位的目标表示u_-int128类型的整数常量。所以我想说,从技术上讲,这不是一个bug,因为它不受支持。@ShafikYaghmour:事实上,
long
long
在我的平台上都是
64位的。所以我明白我不能依赖上面的任何整数常量来工作!非常感谢您的澄清。我同意这是一种奇怪的行为,但由于它不受支持,这似乎等同于说它是未定义的行为,因此您可以预期鼻恶魔之类的行为。@Marglisse好的,标准将此留给实现,gcc文档说它不受支持。这似乎在功能上等同于未定义的行为。那么,不一致的行为不是应该发生的吗?仅仅因为你没有法律强制你做一些聪明的事情并不意味着你应该做一些荒谬的事情(使用_int128,但告诉用户你使用的是未签名的类型)。QoI很重要,值得缺陷报告。
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)