Dav*_*vid 3 c++ debugging virtual gdb
我刚刚注意到一些奇怪的事情,当我在类中添加“虚拟关键字”(除构造函数之外的任何函数)时,我无法在 GDB 中显示对象的内容。GDB 说“不完整类型”
这是代码:
////////////////reco.h //////////////
#ifndef RECO_H
#define RECO_H
#include <iostream>
#include <string>
class reco {
public:
reco(float weight);
~reco(void);
float getWeight();
private:
float weight;
};
#endif
Run Code Online (Sandbox Code Playgroud)
/////////////////reco.cpp //////////////
#include <iostream>
#include <string>
#include "reco.h"
using namespace std;
reco::reco(float weight) {
weight = weight;
}
reco::~reco(void) {
cout << "destructor reco" << endl;
}
float reco::getWeight() {
return weight;
}
Run Code Online (Sandbox Code Playgroud)
////////////// main.cpp //////////////
#include <iostream>
#include <string>
#include "reco.h"
using namespace std;
int main() {
reco* s = new reco(5.0);
cout << s->getWeight() << endl;
delete s;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后使用GDB:
gdb main.exe
breakpoint main.cpp:11 <---- (cout)
run
print *s
$1 = { weight = 5 }
Run Code Online (Sandbox Code Playgroud)
然后,如果我将其中一个函数设置为“虚拟”,然后我重新尝试*s
使用 GDB 打印我的指针,它会显示:“不完整类型”
看起来 VTABLE 发生了一些事情,就好像“virtual”关键字隐藏了我的 Reco 类的实现。我知道编译器会进行后期绑定,然后 VTABLE 查找是在运行时完成的,但是当 GDB 调试它时程序已经在运行,对吗?
将“set print vtbl”设置为“on”。
如果我使用ptype s
,我会<incomplete type>
再次收到该消息。
如果我用 检查地址x/540f80
,它会说“无法访问内存”
我不知道为什么仅仅添加这个关键字就会使我的对象的类型不完整?
非常感谢你的帮助 !
我注意到的最后一件事:
虚拟:
reco.cpp -> g0 and main.cpp -> g = incomplete type
reco.cpp -> g and main.cpp ->g = ok
Run Code Online (Sandbox Code Playgroud)
没有虚拟
reco.cpp -> g0 and main.cpp -> g = ok
reco.cpp -> g and main.cpp ->g = ok
Run Code Online (Sandbox Code Playgroud)
reco.cpp -> g and main.cpp ->g = ok
假设-> g
您的意思是使用reco.cpp
该-g
标志进行编译,是的,这样做,而不是这样做:
g++ -c -g0 reco.cpp
Run Code Online (Sandbox Code Playgroud)
您发现,如果GCC知道您有一个关键方法,它可以优化它必须发出的调试信息量。
如果没有virtual
,就没有关键方法,并且 GCC 必须将冗余的调试信息发送到每个编译单元中。这会使您的目标文件更大(它对最终的可执行文件影响很小或没有影响),但即使只有部分目标文件使用调试信息进行编译,您也可以进行调试。