gcc用long而不是__int128实例化模板
gcc instantiates template with long instead of __int128
我感到茫然和困惑。对我的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.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)
由于OP已经确认long-long在他们的系统上是64位的,我们可以看到128位Integers上的gcc文档说:
GCC不支持为长整型小于128位宽的目标表达__int128类型的整数常量。
因此,虽然我同意这种行为很奇怪,但从技术上讲,它不是一个bug,因为gcc不支持这种场景,并明确记录了这种情况。
编译器可能支持C++11标准草案3.9.1:中的扩展有符号整数
也可能存在实现定义的扩展有符号整数类型
但它们是实现定义的,第2.14.2节中整数文字的措辞是:
如果整数文本不能由其列表中的任何类型表示,则扩展整数类型(3.9.1)可以表示其值,则可能具有扩展整数类型[…]
强调可能。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 对显式实例化的模板函数的未定义引用
- [temp.variadic]中关于包扩展实例化的措辞