如何防止编译器省略未显式实例化的类型?
How do I prevent the compiler from omitting types I don't explicitly instantiate?
情况
这是一个关于调试的问题。我已经为标准库安装了GDB漂亮的打印机,但我发现它们在许多情况下都不能正常工作。例如,使用以下声明调试一段代码:
std::map<int, int> foo;
我已经使用-O0 -ggdb3
进行了编译,所以我希望在检查foo
时不会遇到任何问题,如果我手动检查结构,我也不会遇到问题。然而,STL漂亮的打印机不起作用,因为GCC似乎忽略了我的程序没有显式实例化的嵌套类型的类型信息。
例如,如果我在GDB中运行以下命令:
p foo.begin()
我看到以下错误消息:
Python Exception <class 'gdb.error'> No type named
std::_Rb_tree_iterator<std::pair<int const, int> >::_Link_type.
这个缺少的typename是一个内部typedef,在std::map::iterator
内部定义。它是依赖于实现的标准库支持代码,因此它不是跨平台的(甚至不能保证在同一平台上的不同版本的实现之间继续存在)。
然而,如果我在程序中声明了涉及该类型的内容,那么漂亮的打印机将正常工作。
std::_Rb_tree_iterator<std::pair<int const, int> >
::_Link_type *dummy = NULL;
问题
那么,在这种情况下,我如何指示GCC不要删除类型的定义,以便它们对调试器仍然可用呢?考虑到STL实现不是跨平台的,像用预处理器宏声明一堆伪变量这样的破解方法似乎不是一个可扩展的解决方案。有没有一个我可以传递给GCC的标志来强制递归包含模板类型?或者GCC根本不支持这一点?有没有其他人面对并解决了这个问题?
作者说明
GDB漂亮的打印在GDB 7.7.1中被破坏(截至本文撰写时,ubuntu 14.04 repos中的最新版本),无法正确打印指针。那些想回答这个问题的人可能会发现,知道这是一个已知的问题,并且已经提交了一个bug,这很有用。
那么,在这种情况下,我如何指示GCC不要删除类型的定义,以便它们对调试器仍然可用?
我认为没有任何方法可以指示GCC为程序中不存在的类型发出调试信息。
然而,这是一个非常奇怪的程序,它实例化了std::map
,但从未使用任何迭代器使用方法。
如果我在程序中声明了涉及该类型的内容
应该没有必要这么做。简单地调用m.begin()
或在程序中的某个映射上有一个范围for
循环就足以实例化迭代器类型。
- 检查某些类型是否是模板类 std::optional 的实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 实例化模板时,我是否必须显式显示参数包中的类型?
- 在实例化之前推断函数模板的返回类型
- 对象实例化与类型C++
- 使用用户定义的类型 UDT 实例化 std::atomic<>。如果 UDT 具有虚函数,则 l 墨水将失败。为什么?
- 根据实例化点期望不同的类型
- 类模板实例化中的类型转换
- 实例化具有不完整类型的类模板格式不正确(如果该类型是在之后定义的)
- 实例化多种类型的成员函数模板
- C++ 多态模板类,模板类型对象的实例化
- 从模板实例化/类型推断中查找错误消息的实际来源
- MPL地图实例化类型
- SFINAE将实例化类型限制为std::chrono::duration类型
- 实例化类型模板化类的非类型模板化成员函数
- 使用大括号初始化列表或传统的 ctor 语法实例化类型
- 何时检查C++模板实例化类型
- 使LLDB将地址重新解释为指向模板实例化类型对象的指针
- 标准::shared_ptr 失去常量的实例化类型
- c++模板:我可以/如何使用结构体作为模板的实例化类型