Solved Windows: Crash when connecting a signal and slot in the constructor of a globally scoped object
-
The following program will crash when I compile and run it in Qt Creator on Windows:
TestObject.h:
#include <QObject> class TestObject : public QObject { Q_OBJECT public: TestObject(QObject *parent = nullptr); signals: void signal(); public slots: void slot(); };
TestObject.cpp:
#include "TestObject.h" TestObject::TestObject(QObject *parent) : QObject(parent) { connect(this, &TestObject::signal, this, &TestObject::slot); } void TestObject::slot() {} TestObject global; int main(int argc, char *argv[]) { TestObject local; return 0; }
If I remove either the call to
connect
in TestObject's constructor orTestObject globalVar;
then there's no crash. Something about callingconnect
in the constructor of a globally scoped is going wrong. The locally scoped variable inmain()
doesn't cause any issues.I've tried compiling against Qt 5.9.9, 5.11.2, and 5.14.2, and they all have the same crash.
If I compile the same program on macOS, there's no crash.
Is there something I'm doing wrong, or some way to work around this issue?
-
Hi,
Your global object is wrong. QObject based classes should only be instanciated after QCoreApplication.
-
@SGaist Are you sure? I've never read in any Qt documentation that
QCoreApplication
is required at all, much less required to be instantiated before any otherQObject
instance. (If that is mentioned in the docs, please feel free to point me to it.) My understanding is that it's required if you want your app to have an event loop. Further instantiating an instance ofTestObject
inmain()
withoutQCoreApplication
seems to work fine. -
This code can run without crash in Qt MinGW but not in Qt MSVC.
I think it is because the create order of global variables.
You see, when connect, it need a static object of the sender and the receiver object's class.
If the static object, which is also a global variable, is not created before the other global variable, then the application will crash. -
@Bonnie That makes sense.
Also another person pointed me towards this: https://doc.qt.io/qt-5/threads-qobject.html#qobject-reentrancy
So @SGaist you are correct. I'll find something else to do other than using globally-scoped
QObject
instances.I do wish Qt's documentation would mention this on the page for
QObject
. It strikes me as quite important! -
In the QCoreApplication doc, it's written that this class or one of its derivative shall be the first object.