[Development] HEADS UP: do not pass const objects to QObject::disconnect(const QMetaObject::Connection&)!
Marc Mutz
marc.mutz at qt.io
Thu Mar 26 19:41:38 CET 2026
Hi,
We Qt developers cannot figure out how to proceed from here, so let me give you a heads-up here, so you can take matters into your own hands.
TL;DR: never pass Connection objects originally declared const to QObject::disconnect(Connection).
The function const_cast<>s away the const of the argument to reset the d_ptr to nullptr. It doesn't matter why, suffice to say that it's not trivial to fix either way on the Qt side.
It _is_ trivial to fix on the user side: Just don't pass const objects.
If you don't pass const objects, you're on the safe side. Period. End of story.
If you pass const objects, but they're not _originally_ marked as const (e.g. you're using const_iterators over a QList<Connection>, then there's also nothing to do, but, depending on how the story unfolds, you may get deprecation warnings in the future.
If you pass const objects _originally marked as const_ (e.g. the key of a std::map, or an object you declared const yourself:
const auto c = QObject::connect(~~~~);
~~~~
QObject::disconnect(c); // UB!!
Then you need to take action: make the Connection object _not_ originally const. In the case above, do
auto c = QObject::connect(~~~~); // NOT const!
if you don't control the declaration (e.g. its a key in a std::map), then DO NOT CALL disconnect() on it. Take a copy and call disconnect() on that:
const c = QObject::connect(~~~~); // can't change this even if I tried
~~~~
auto copy = c; // take a copy
QObject::disconnect(copy); // and only disconnect() the copy
The connection will be disconnected either way, it suffices if any of the copies of the Connection gets passed to disconnect() (but memory is held longer, until `c` is actually destroyed, there is no way to prevent that - that's exactly the UB).
Patch your code, and pick to all your branches. You do _not_ need to update your production Qt. This fix even fixes it for Qt versions that are out of support!
In all of Qt, we have so found _one_ instance of the latter. And the fix was just to drop the const from the declaration. The vast majority is just precautionary
- for (const auto &c : std::as_const(m_connections))
+ for (auto &c : m_connections)
QObject::disconnect(c);
In anticipation of a deprecation of the const overload. If you would like compiler help in finding affected code, apply the patch from https://codereview.qt-project.org/c/qt/qtbase/+/724503/4/src/corelib/kernel/qobject.h to qobject.h (only the header, the .cpp file is just comments). You do not need to patch your production Qt. You only need to install this patch on a developer machine, or the CI, and fix the deprecated calls. The resulting executable will be forward and backward compatible with the unpatched Qt.
Sorry for the annoyance, and for failing to detect the issue sooner, but this is really only fixable at the user side.
Please help spread the word!
Thanks,
Marc
--
Marc Mutz <marc.mutz at qt.io><mailto:marc.mutz at qt.io> (he/his)
Principal Software Engineer
The Qt Company
Erich-Thilo-Str. 10 12489
Berlin, Germany
www.qt.io<http://www.qt.io>
Geschäftsführer: Mika Pälsi, Juha Varelius, Jouni Lintunen
Sitz der Gesellschaft: Berlin,
Registergericht: Amtsgericht Charlottenburg,
HRB 144331 B
Public
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20260326/8b60c50b/attachment.htm>
More information about the Development
mailing list