如何防止编译器省略未显式实例化的类型?

How do I prevent the compiler from omitting types I don't explicitly instantiate?

本文关键字:实例化 类型 何防止 编译器省      更新时间:2023-10-16

情况

这是一个关于调试的问题。我已经为标准库安装了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循环就足以实例化迭代器类型。