Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Is "moc" actually helping to debug?



  • Here is one of the many explanations about "moc"

    The moc tool reads a C++ source file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces another C++ source file which contains the meta-object code for each of those classes. This generated source file is either #include'd into the class's source file or, more usually, compiled and linked with the class's implementation.

    I just added one of mine previously incomplete and not working project to my main SUB_DIRS project.

    As expected I am getting ton of complains from build.

    I can handle / correct "undefined" OR "multiple defined" stuff in source code.

    What I am having issues are many "moc" messages and how to track their source.

    Now since "The moc tool reads a C++ source file." I assume the errors ARE indeed in source code.
    But "clinking on moc error" brings up a moc generated file which seems futile to even try to analyze.

    Can I - for simplicity - disable "moc" errors so I can at least concertrate on real source errors ?

    Naively - if "moc" generated errors are from "reading source" I should be able to disable "moc" - at least temporary..

    Any suggestion where / how ?

    ADDENDUM
    I have "removed" all "moc' files from the project .

    Now I am getting this

    /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x28): undefined reference to BT_TabWidget::~BT_TabWidget()' /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x30): undefined reference toBT_TabWidget::~BT_TabWidget()'
    /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x1d0): undefined reference to non-virtual thunk to BT_TabWidget::~BT_TabWidget()' /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x1d8): undefined reference tonon-virtual thunk to BT_TabWidget::~BT_TabWidget()'

    Basically down to manageable number of errors telling me why the object file could not be build .,

    Now how do I go from "undefined reference " to SOURCE where such reference is missing ?

    Since the whatever (compiler /make ect) KNOWS it is missing why it cannot tell me WHERE it is missing ?
    Best guess would be better that what I am getting now.

    Any help would be appreciated.


  • Moderators

    @AnneRanch said in Is "moc" actually helping to debug?:

    The moc tool reads a C++ source file. If it finds one or more class declarations that contain the Q_OBJECT macro, it produces another C++ source file which contains the meta-object code for each of those classes. This generated source file is either #include'd into the class's source file or, more usually, compiled and linked with the class's implementation.

    Yes, that's correct.

    I just added one of mine previously incomplete and not working project to my main SUB_DIRS project.
    As expected I am getting ton of complains from build.
    I can handle / correct "undefined" OR "multiple defined" stuff in source code.
    What I am having issues are many "moc" messages and how to track their source.

    You don't, you rerun qmake to re-generate the moc files.

    Now since "The moc tool reads a C++ source file." I assume the errors ARE indeed in source code.

    Yes, it's a C++ file.

    But "clinking on moc error" brings up a moc generated file which seems futile to even try to analyze.

    No need, just assume the moc is correct. What you should suspect is it being out of date, so, as said, rerun qmake to fix this.

    Can I - for simplicity - disable "moc" errors so I can at least concertrate on real source errors ?

    No. The C++ code is incomplete without the moc files, specifically the calls into the meta-type system and the ones into QMetaObject, which includes most notably signals (and their connected slots).

    Naively - if "moc" generated errors are from "reading source" I should be able to disable "moc" - at least temporary..

    No. At least not with any sensible effect.

    /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x28): undefined reference to BT_TabWidget::~BT_TabWidget()' /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x30): undefined reference toBT_TabWidget::~BT_TabWidget()'
    /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x1d0): undefined reference to non-virtual thunk to BT_TabWidget::~BT_TabWidget()' /usr/bin/ld: moc_bt_tabwidget.o:(.data.rel.ro._ZTV12BT_TabWidget[_ZTV12BT_TabWidget]+0x1d8): undefined reference tonon-virtual thunk to BT_TabWidget::~BT_TabWidget()'

    Yes, that one's on you, not the moc. I imagine you forgot to actually implement the destructor.

    Now how do I go from "undefined reference " to SOURCE where such reference is missing ?

    From the name of the missing reference, no place else.

    Since the whatever (compiler /make ect) KNOWS it is missing why it cannot tell me WHERE it is missing ?

    Because it doesn't know where it is missing. That's a linker error, it comes at a such stage of the build process where sources no longer exist, nor do line numbers, nor C++ for that matter. It links object files together, that is it works with symbols and references to those symbols. It has no notion of where this has happened, it can only tell that it happened and what symbol is missing.



  • @AnneRanch said in Is "moc" actually helping to debug?:

    Since the whatever (compiler /make ect) KNOWS it is missing why it cannot tell me WHERE it is missing ?
    Best guess would be better that what I am getting now.

    I don't have any children. Can you tell me where my son Gary isn't? It's impossible to point to a specific place and say that's where something isn't. If it doesn't exist, it isn't everywhere.

    It's up to you to decide where you want to put it. If you have all your function implementations for BT_TabWidget in a particular file, then put the missing destructor there. But there's no hard requirement that all of the methods for a class have to be implemented in one particular file. If it's a really big class, it may make sense to break up the methods into different source files. So you have have t read the linker error

    undefined reference to BT_TabWidget::~BT_TabWidget()

    And decide where you what to define it. The name of the class, BT_TabWidget, is about the best hint that the linker knows how to give you.



  • Let me put this the silliest way - if I do not have an object BT_TabWidget constructed nowhere in the code then I am getting "you are missing destructor SOMEWHERE " from all of this.

    And I will not ask why I am not getting "no BT_TabWidget (object) found " instead., So I will go back to code and verify all BT_TabWidget CODE myself.



  • @AnneRanch it looks like old moc generated files still exists, check build directory / whether shadow build is enabled.
    moc_bt_tabwidget.o link error means
    moc has generated "moc_bt_tabwidget.cpp" file from the input source file bt_tabwidget.cpp,
    but it is not able to link, check whether bt_tabwidget.cpp included in the project.


  • Moderators

    @AnneRanch said in Is "moc" actually helping to debug?:

    Let me put this the silliest way - if I do not have an object BT_TabWidget constructed nowhere in the code then I am getting "you are missing destructor SOMEWHERE " from all of this.

    And I will not ask why I am not getting "no BT_TabWidget (object) found " instead., So I will go back to code and verify all BT_TabWidget CODE myself.

    When you compile stuff, the assembly is generated for the classes not the objects. There's no requirement that you must have an instance of some class to have the latter compiled into code. Or to put it the silliest way I can think of: classes are not objects, nor vice versa.
    As far as C++ goes, all virtual functions shall be defined if they're not a pure virtual for the build process to succeed, and if you go through your code I'm sure you're going to find out that this particular class has a destructor, which was declared (hence it's an override due to its base class' destructor being virtual), and that destructor hasn't been defined.

    @wrosecrans said in Is "moc" actually helping to debug?:

    I don't have any children. Can you tell me where my son Gary isn't? It's impossible to point to a specific place and say that's where something isn't.

    lol!

    If it doesn't exist, it isn't everywhere.

    We could argue some quantum mechanics about that ... ;)


Log in to reply