具有C ++虚函数时GDB不完整类型

时间:2015-04-07 14:32:06

标签: c++ debugging gdb virtual

我刚刚注意到一些奇怪的东西,当我添加"虚拟关键字"在我的类(除了构造函数之外的任何函数)中,我无法在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

///////////////// 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;
}

然后使用GDB:

gdb main.exe
breakpoint main.cpp:11 <---- (cout)
run
print *s
$1 = { weight = 5 }

然后,如果我创建其中一个函数&#34; virtual&#34;,然后我重新尝试用GDB打印我的*s指针,它会说: &#34;不完整类型&#34;

看起来VTABLE正在发生一些事情,好像&#34;虚拟&#34;关键字隐藏了我的Reco类的实现。我知道编译器会进行后期绑定,然后VTABLE查找在运行时完成,但是在GDB调试时程序已在运行,对吗?

&#34;设置print vtbl&#34;设置在&#34; on&#34;。

如果我使用ptype s,我会再次收到<incomplete type>消息。

如果我使用x/540f80检查地址,则表示&#34;无法访问内存&#34;

我不知道为什么只添加此关键字会导致我的对象类型不完整?

非常感谢你的帮助!

我注意到的最后一件事:

WITH VIRTUAL:

 reco.cpp -> g0 and main.cpp -> g = incomplete type
 reco.cpp -> g and main.cpp ->g = ok

没有虚拟

 reco.cpp -> g0 and main.cpp -> g = ok
 reco.cpp -> g and main.cpp ->g = ok

1 个答案:

答案 0 :(得分:4)

  

reco.cpp -> g and main.cpp ->g = ok

假设您-> g表示您使用reco.cpp标记编译-g,是执行,并且不要< / em>这样做:

g++ -c -g0 reco.cpp

您发现GCC可以优化其必须发出的调试信息的数量如果它知道您拥有key method

没有virtual,没有密钥方法,GCC必须将冗余调试信息发送到每个编译单元。这会使您的目标文件变大(它对最终的可执行文件几乎没有影响),但即使只使用调试信息编译了一些目标文件,也可以进行调试。