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

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 or TestObject globalVar; then there's no crash. Something about calling connect in the constructor of a globally scoped is going wrong. The locally scoped variable in main() 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?


  • Lifetime Qt Champion

    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 other QObject 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 of TestObject in main() without QCoreApplication 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!


  • Lifetime Qt Champion

    In the QCoreApplication doc, it's written that this class or one of its derivative shall be the first object.


Log in to reply