[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