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

GDB incomplete type when having C++ virtual function

我刚刚注意到一些奇怪的事情,当我在我的 class 中添加 "virtual keyword"(除构造函数之外的任何函数)时,我无法在 GDB 中显示我的对象的内容。 GDB 说 "incomplete type"

这是代码:

////////////////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
 = { weight = 5 }

然后,如果我创建其中一个函数 "virtual",然后我再次尝试使用 GDB 打印我的 *s 指针,它说: "incomplete type"

VTABLE 似乎发生了一些事情,好像 "virtual" 关键字隐藏了我的 Reco class 的实现。我知道编译器会进行后期绑定,然后 VTABLE 查找是在运行时完成的,但是程序已经 运行 而 GDB 正在调试它,对吗?

"set print vtbl"设置在"on".

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

如果我用 x/540f80 检查地址,它说 "cannot access memory"

我不知道为什么只添加这个关键字会使我的对象的类型不完整?

非常感谢您的帮助!

我注意到的最后一件事:

虚拟:

 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

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

假设 -> g 你的意思是你用 -g 标志编译 reco.cpp,是的 do,并且 不要这样做:

g++ -c -g0 reco.cpp

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

没有virtual,就没有关键方法,GCC 必须将冗余 调试信息发送到每个 编译单元。这会使您的目标文件更大(它应该对最终的可执行文件影响很小或没有影响),但允许您进行调试,即使只有部分目标文件是使用调试信息编译的。