Qt: a missing vtable usually means the first non-inline virtual member function has no definition

clang, qt

Solution

Assuming we're dealing with `qmake`.

The golden rules are:

- Make sure the `Q_OBJECT` macro is present in the definition of all `QObject`-derived classes.

- Make sure you declare your `QObject`-derived classes in your header files only.

- Make sure all of your header files are listed in your .pro file in the `HEADERS=` list.

- Run `qmake` every time you add `Q_OBJECT` to one of your classes or modify your `.pro` file.

Explanation

EDIT 1: The error goes away if I comment out Q_OBJECT from the declation of MSFSPlugin::MSFSPluginImpl, but then I lose the signal functionality.

Yup. `Q_OBJECT` is needed for declaring signals, slots, invokables, `qobject_cast`, translations, properties, enums and methods introspection, and so on.

The #1 golden rule comes from the fact that without `Q_OBJECT` you can't use stuff like `qobject_cast` on your class; if you use (even indirectly) introspection facilities, for instance to debug an object hierarchy or to dump all active connections to an object, then objects of your class will have the real class name shown (and not the one of the superclass); etc.

`Q_OBJECT` does two things:

- it tells builsystems to add calls to `moc`, whose job is to generate some extra code for the class. This code will provide all the facilities listed above;

- since it's a normal C++ macro, when compiled it expands to a few declarations, including a couple of virtuals: `qt_metacall()` and `metaObject()`. `moc` will generate the implementation for these virtuals.

The error you get is the typical symptom of having declared the virtuals (because the macro was expanded in your code) but `moc` wasn't run, you had some unimplemented virtuals which will make the linking fail.

With gcc and GNU ld, you get an even more cryptic error, about an `undefined reference to vtable for ClassName`. Of course, googling such errors will immediately tell you how to solve the issue.

EDIT 2: I see moc operates on header files only. Could this be related to the fact that my QObject derived class is declared & defined in a .cpp file?

So, the question is: why wasn't `moc` run on a file containing a definition of a class with the `Q_OBJECT` macro?

When we use `qmake` to generate your Makefiles, then qmake will scan all the header files listed in the `HEADERS` variable. When it finds that a header contains a class definition with the `Q_OBJECT` macro, it will also emit instructions (in the Makefile) to run `moc` over that header, compile `moc`'s output and link the resulting object in the final target.

And we have rules #2, #3, #4 right here.

#2 tells us to put `Q_OBJECT` classes in headers; and that's because `HEADERS` lists headers, not sources.

#3 tells us to indeed put all headers into the `HEADERS` list. That obviously because if a header containing a `Q_OBJECT` is not in that list, then `qmake` won't find it and emit the rules. (While not strictly necessary for headers not containing QObject subclasses, it's good practice to put every header in there in order to forget none.)

#4 tells us to re-run `qmake` every time we add `Q_OBJECT` or modify the `.pro` file. The reason for the first part of the rule is that if `qmake` already scanned a header and found no `Q_OBJECT`, then it didn't emit any rules in the Makefile. But adding `Q_OBJECT` also needs those rules; hence we need `qmake` to re-scan the headers, and that's precisely what re-running `qmake` does.

The same reason applies when the `.pro` is modified (for instance, when adding more headers -- maybe with `Q_OBJECT` under `HEADERS`).

Note that if you're using a GNU-like `make`, then `qmake` will emit a special rule that tells `make` to re-run `qmake` and then restart the Makefile, if the `.pro` gets modified after the Makefile. That's why usually on UNIX you don't need to manually re-run `qmake` when you modify your `.pro` -- just running `make` will also run `qmake` again. But this doesn't work everywhere.

So, is it impossible to have classes definition containing `Q_OBJECT` in a `.cpp` file?

No, it's perfectly possible, but it requires using a somehow undocumented `qmake` feature. The trick is adding a line like:

#include "foobar.moc"

at the end of the `foobar.cpp` file, file that contains one of more class definitions with `Q_OBJECT`.

`qmake` will find this special inclusion and generate a rule for `moc` to create `foobar.moc`, which will then be included by the `.cpp` and thus compiled together with it. (Hence, there will be no extra rules for compiling `foobar.moc` nor to link the result.)

Problem

There are numerous threads on this all over. None seems to fit my bill. I'm getting the following linker errors in my code: ``` Undefined symbols for architecture x86_64: "vtable for MSFSPlugin::MSFSPluginImpl", referenced from: MSFSPlugin::MSFSPluginImpl::MSFSPluginImpl(QObject*) in MSFSPlugin.o MSFSPlugin::MSFSPluginImpl::~MSFSPluginImpl() in MSFSPlugin.o NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` It should have been something obvious as - a missing vtable usually means the first non-inline virtual member function has no definition. However, I don't see what I'm missing: I have this class declation in `MSFSPlugin.h`: ``` class MSFSPlugin : public QObject, public IMediaSource { Q_OBJECT Q_INTERFACES(IMediaSource) ... protected: class MSFSPluginImpl; MSFSPluginImpl* mImpl; } ``` Then in `MSFSPlugin.cpp`, I have the following: ``` class MSFSPlugin::MSFSPluginImpl : public QThread { Q_OBJECT public: MSFSPluginImpl(QObject *parent = 0); virtual ~MSFSPluginImpl(); QString getSourceDirectory() const; void setSourceDirectory(QString sourceDirectory); signals: void loadDirectoryFinished(bool success); protected: QString mSourceDirectory; }; ``` Followed by definitions: ``` MSFSPlugin::MSFSPluginImpl::MSFSPluginImpl(QObject *parent) : QThread(parent) { } MSFSPlugin::MSFSPluginImpl::~MSFSPluginImpl() { } QString MSFSPlugin::MSFSPluginImpl::getSourceDirectory() const { return mSourceDirectory; } void MSFSPlugin::MSFSPluginImpl::setSourceDirectory(QString sourceDirectory) { mSourceDirectory = sourceDirectory; } ... ``` In short, I don't think I'm missing any non-inline virtual member function definition. I'm using: ``` Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.1.0 Thread model: posix ``` Additional Info: In my `moc_MSFSPlugin.cpp` I don't see the autogenerated `Q_OBJECT` related code for class `MSFSPlugin::MSFSPluginImpl` which indirectly (via QThread) derives from `QObject`. Specifically, I don't see code generated for the signal, declared in that class (`loadDirectoryFinished`). Could this be the problem? EDIT 1: The error goes away if I comment out `Q_OBJECT` from the declation of `MSFSPlugin::MSFSPluginImpl`, but then I lose the signal functionality. EDIT 2: I see moc operates on header files only. Could this be related to the fact that my QObject derived class is declared & defined in a .cpp file?

Original source