具有C ++虚函数的GDB不完整类型 [英] GDB incomplete type when having C++ virtual function
问题描述
这是代码:
///////// /////// reco.h /////////////
#ifndef RECO_H
#define RECO_H
#include< iostream>
#include< string>
class reco {
public:
reco(float weight);
〜reco(void);
float getWeight();
私人:
浮动重量;
};
#endif
/////////// ////// reco.cpp /////////////
#include< iostream>
#include< string>
#includereco.h
using namespace std;
reco :: reco(float weight){
weight = weight;
}
reco ::〜reco(void){
cout<< 析构器回收<终点
}
float reco :: getWeight(){
return weight;
}
////////////// main。 cpp /////////////
#include< iostream>
#include< string>
#includereco.h
using namespace std;
int main(){
reco * s = new reco(5.0);
cout<<< s-> getWeight()<<终点
删除s;
return 0;
}
然后用GDB:
gdb main.exe
breakpoint main.cpp:11< ----(cout)
run
print * s
$ 1 = {weight = 5}
然后,如果我做了一个虚拟 ,并重试打印我的 * s
指针与GDB,它说:
不完整类型
看起来VTABLE有一些事情,就像virtual关键字隐藏了我的Reco类的实现一样。我知道编译器晚期绑定,然后,VTABLE查找是在运行时完成的,但程序已经在运行,而GDB正在调试,对吧?
设置打印vtbl设置在开。
如果我使用 ptype s
,我得到<不完全类型>
消息。
如果我用 x / 540f80
,它说无法访问内存
我不知道为什么添加这个关键字使我的对象的类型不完整?
非常感谢您的帮助!
最后一件事我注意到:
WITH VIRTUAL:
reco.cpp - > g0和main.cpp - > g =不完整的类型
reco.cpp - > g和main.cpp - > g = ok
无虚拟
reco.cpp - > g0和main.cpp - > g = ok
reco.cpp - > g和main.cpp - > g = ok
reco.cpp - > g和main.cpp - > g = ok
假设由 > g
您的意思是您使用 -g
标记编译 reco.cpp
em> do ,和不要这样做:
g ++ -c -g0 reco.cpp
你发现是GCC可以优化调试信息的数量如果知道您有关键方法,则必须发出
没有 virtual
,没有关键的方法,GCC必须发出冗余将信息调试到每个编辑单元。这使得您的对象文件更大(对最终的可执行文件应该几乎没有影响),但是即使只有一些对象文件使用调试信息进行编译,也允许调试。
I have just noticed something weird, when I add the "virtual keyword" in my class (any function except the constructor), I can't display the content of my object in GDB. GDB says "incomplete type"
Here is the code :
//////////////// 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
///////////////// 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;
}
////////////// 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;
}
Then with GDB :
gdb main.exe
breakpoint main.cpp:11 <---- (cout)
run
print *s
$1 = { weight = 5 }
And then, if I make one of the functions "virtual", and I retry to print my *s
pointer with GDB, it says:
"incomplete type"
It looks like there is something happening with the VTABLE, as if the "virtual" keyword was hiding the implementation of my Reco class. I know that the compiler does late binding and then, the VTABLE lookup is done at runtime, but the program is already running while GDB is debugging it, right ?
The "set print vtbl" setting in "on".
If I use ptype s
, I get the <incomplete type>
message again.
If I examine the address with x/540f80
, it says "cannot access memory"
I don't know why just adding this keyword makes my object's type incomplete ?
Thanks a lot for your help !
One last thing that I notice :
WITH VIRTUAL:
reco.cpp -> g0 and main.cpp -> g = incomplete type
reco.cpp -> g and main.cpp ->g = ok
WITHOUT VIRTUAL
reco.cpp -> g0 and main.cpp -> g = ok
reco.cpp -> g and main.cpp ->g = ok
reco.cpp -> g and main.cpp ->g = ok
Assuming by -> g
you mean that you compile reco.cpp
with the -g
flag, yes do that, and don't do this:
g++ -c -g0 reco.cpp
What you've discovered that is that GCC can optimize the amount on debug info it must emit if it knows that you have a key method.
Without virtual
, there is no key method, and GCC must emit redundant debug info into every compilation unit. That makes your object files larger (it should have little or no effect on the final executable), but allows you to debug even when only some of your object files are compiled with debug info.
这篇关于具有C ++虚函数的GDB不完整类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!