GDB incomplete type when having C++ virtual function

痞子三分冷 提交于 2020-01-04 14:17:43

问题


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

回答1:


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.



来源:https://stackoverflow.com/questions/29494132/gdb-incomplete-type-when-having-c-virtual-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!