2015-11-06 58 views
3

我感到茫然和困惑。第二次打电话给我的big模板时发生了什么?gcc实例化模板与长而不是__int128

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.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) 
+1

假设long long在你的平台上不是128bit,那么[gcc docs say](https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html)* GCC中不支持表示整数常量对于长整型长度小于128位的目标,__int128类型*所以我认为这在技术上不是bug,因为它不被支持。 –

+0

@ShafikYaghmour:在我的平台上,“long”和“long long”都是“64bit”宽。所以我明白,我可以**不**依赖于我的任何我的整数常量上面工作!非常感谢您澄清。 –

+0

我同意这是奇怪的行为,但由于它是不受支持的,它似乎相当于说它是未定义的行为,因此你可以指望鼻子恶魔等等。 –

回答

1

由于OP已经确认长长的是64位的系统上,我们可以看到,gcc docs on 128-bit Integers说:

中有不支持GCC用于为长整数长度小于128位的目标表达一个__int128类型的整数常量。

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

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

还可以有实现定义的扩展符号整数类型

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

如果整数文字不能由其列表中的任何类型表示,并且扩展ED整数类型(3.9.1)可以 表示其值,它可能具有扩展整型[...]

重点放在可以