[Development] Not delivering signals to slots in class sub-objects already destroyed

Thiago Macieira thiago.macieira at intel.com
Wed Sep 3 23:29:25 CEST 2025


On Wednesday, 3 September 2025 03:23:30 Pacific Daylight Time Lars Knoll via 
Development wrote:
> I was thinking about a slightly different approach, namely storing store the
> meta object pointer that the object has when creating the connection in the
> connection object, you can with one pointer comparison determine whether
> the object is still fully constructed. That should cover most of the signal
> emissions with one pointer comparison. If object->metaObject !=
> connection->metaObject, you can take the slower path that Thiago proposes
> and iterate over the meta object chain.

I thought about that but rejected that idea for two reasons. The first is that 
it requires storing a full pointer, instead of a 32- or even 16-bit integer 
(65535 classes will be enough for everyone).

The second is what you mentioned:

> The problem with that approach is that it wouldn't work well for connections
> created in the constructor of a parent class.

You need to verify whether inheritance works, not just equality. Calling 
connect() during object construction is fairly common and the connection must 
work when a derived class finishes constructing too. The two loops are very 
similar in fact:

inherits:
    const QMetaObject *m = this;
    do {
        if (metaObject == m)
            return true;
    } while ((m = m->d.superdata));
    return false;

depth:
    int depth = -1;
    do {
        ++depth;
        metaObject = metaObject->superClass();
    } while (metaObject);
    return depth;

The advantage is that in a normal situation, the inherits loop may finish 
earlier, potentially immediately, without going all the way to QObject.

> So I think your approach is better, one complication could be classes in the
> hierarchy without a Q_OBJECT macro (that are later gaining one), but moc
> should see those as well, and can count them into the depth.

I don't see much of a solution for this. The problem are the most derived 
classes with PMFs and no Q_OBJECT, so moc will never see them. The ones in the 
middle of a hierarchy are much less common and are protected against delivery 
- the worst problem is that they wouldn't get delivered if the next Q_OBJECT 
was already destroyed, instead of UB.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Principal Engineer - Intel Platform Engineering Group
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5150 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20250903/e8c61d56/attachment-0001.bin>


More information about the Development mailing list