Reputation: 2379
I am dazed and confused. What is happening here in the second call to my big
template?
template <class T> void big(T t) { }
int main()
{
big(9223372036854775808); // calls big<__int128>
big(941832094813209483120); // calls big<long>
big(239120938091238093219203810293801923832019); // calls big<__int128>
}
Why is a long template instantiated for 941832094813209483120
, while the two other values get a __int128 template.
This value obviously does not fit inside the long
and seems to result in an overflow (see full gdb session below):
big<long> (t=1048147054022350704) at blob.cpp:1
I observe this with gcc-5.2.0
as well as gcc-4.9.2
, while I use gdb-7.7.1
for debugging.
This is my full gdb
session:
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)
Upvotes: 3
Views: 201
Reputation: 158599
Since the OP has confirmed that long long is 64bit on their system we can see that the gcc docs on 128-bit Integers says:
There is no support in GCC for expressing an integer constant of type __int128 for targets with long long integer less than 128 bits wide.
So while I agree the behavior is odd, it is technically not a bug since gcc does not support this scenario and explicitly documents this.
Compilers may support extended signed integers, from the draft C++11 standard section 3.9.1:
There may also be implementation-defined extended signed integer types
but they are implementation-defined and wording for integer literals in section 2.14.2 says:
If an integer literal cannot be represented by any type in its list and an extended integer type (3.9.1) can represent its value, it may have that extended integer type [...]
with emphasis on may.
Upvotes: 1