如何防止编译器忽略我没有显式实例化的类型?

时间:2015-04-19 21:38:09

标签: c++ debugging types gdb g++

情况

这是关于调试的问题。我已经为标准库安装了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实现不是跨平台的,一个hacky解决方法就像使用预处理器宏声明一堆虚拟变量似乎不是一个可扩展的解决方案。是否有一个标志我可以传递给GCC强制递归包含模板类型?或者GCC根本不支持这个?还有其他人遇到过这个问题并解决了吗?

作者注意事项

在GDB 7.7.1(截至撰写本文时ubuntu 14.04 repos中的最新版本)中打破了GDB漂亮的打印,并且无法正确打印指针。那些想要回答这个问题的人可能会发现知道这是一个已知问题并且已经提交了一个错误很有用。

1 个答案:

答案 0 :(得分:1)

  

那么,我如何指示GCC不要在这种情况下删除类型的定义,以便调试器可以使用它们?

我不相信有任何方法可以指示GCC为您的程序中不存在的类型发出调试信息。

然而,它是一个非常奇怪的程序,它实例化std::map,但从不使用任何迭代器使用方法。

  

如果我在程序中声明涉及该类型的内容

应该没有必要这样做。只需在程序中的某个地方调用m.begin()或在地图上有for循环就足以实例化迭代器类型。