[Development] HEADS UP: do not pass const objects to QObject::disconnect(const QMetaObject::Connection&)!
Volker Hilsheimer
volker.hilsheimer at qt.io
Wed Apr 8 10:27:25 CEST 2026
Having followed the discussion on gerrit for a while, I agree with the following points made there:
- QMetaObject::Connection is a handle- or pointer-like type
There is no reason for it to become move-only (it’s not an owning handle); and as with all handles, the handled object might change even if the handle itself is const. This might result in a change of an observable state.
Our code does not seem fundamentally different from this, which works (as it should) fine with gcc trunk, -O3, and -fsanitize=undefined
https://godbolt.org/z/P4fPG414s
Note that the std::shared_ptr<Connection> object is stored as const, and yet ubsan sees no reason to complain.
- making the modified member mutable strikes me as the best tradeoff: it solves the UB, while not forcing people to modify working and compiling code
That is essentially https://codereview.qt-project.org/c/qt/qtbase/+/721918, once the comments to the commit message are taken into account.
We have zero data points suggesting that any current compiler would optimize the clearing of the member away, or even optimize out the actual disconnect. Nobody has so far produced any (however contrived, such as above) scenario in which this happens. IOW, the risk of this issue causing any real problems is practically zero.
The main argument repeated in the discussion is that this fix requires a recompile as well as Qt upgrade. But given that the issue evidently only materializes with a hypothetical future compiler, a recompile would be needed for that to happen anyway. So that argument seems to bite its own tail.
Cheers,
Volker
> On 27 Mar 2026, at 21:16, Giuseppe D'Angelo via Development <development at qt-project.org> wrote:
>
> Il 27/03/26 08:40, Marc Mutz via Development ha scritto:
>> Hi again,
>> So you see how we can't agree... ;)
>> Absence of proof is not proof of absence.
>
> But a great number of data points makes for an educated estimate.
>
>
>> We don't know what users do out there in the field.
>
> What is this referring to?
>
> If it's referring to the countless ways through which people are storing their Connection objects, passing them around, using them etc., then it's all an argument for not touching these APIs at all, nor to tell users to touch them. The deprecation (or, even worse, moving to a move-only handle) will require annoying changes, all over the place. All of this because we don't want to put `mutable`, and because of a bug with zero impact?
>
> Or if it's referring to the fact that users might be doing sanitized / LTO / who knows what kind of builds and possibly trampling into a manifestation of this UB? Because this claim isn't backed up by data. We know compilers aren't exploiting this UB.
>
> And this doesn't mean we should clearly fix any gratuitous UB we find in Qt. We should and must. And in this case the complete fix is to add `mutable`. Emphasis on "gratuitous", because Qt is actually full of UB that we chose to actively exploit.
>
>
>> All we know is a) the behaviour of the function as of now and b) that if you pass objects originally marked as const, that's UB, according to the standard.
>> We specifically do not know, whether passing const objects actually does "something", we also do not know whether users can upgrade their Qt to receive any of the two other proposed fixes (mutable or not nulling d_ptr).
>
> Sorry, but I reject this argument. *IF* we have a bug in inline code (and I disagree we have one), we fix the bug and tell users to upgrade, and that unfortunately they have to recompile to get the fix. This has nothing to do with the quality of this specific bug: any bug in inline code requires a recompilation.
>
> Any other bug, requires an upgrade but not a recompilation.
>
> But it's not realistic to expect a bug to be fixed without doing anything at all.
>
>
> Also we don't send out emails unless the bug has a provable impact. All indications of this bug point to the fact that there's NO impact. Why are we being alarmist for this one specifically?
>
>
> Finally, for those who can't upgrade and recompile, we might offer mitigation measures, but
> 1) we're in no way obligated to do so, and
> 2) could be as hacky as we like, including an unsupported patch that we don't intend to apply to trunk, ever.
>
> If users can't upgrade their libraries, they'll have to live with bugs in those libraries, and it's not arrogant to state so.
>
>
>> Finally, we do not know whether re-adding the "soft-leak" that nulling the d_ptr plugs is going to hurt anyone out there.
>
> There's no need to go there, `mutable` is the complete fix.
>
>> But all that are speculations. Users to this, compilers don't do that.
>
> It's not a speculation when it's backed by evidence: people have asked compilers to do the optimization we're afraid might be happening in inline code. Compiler authors acknowledged that it's a legit request, and that they're not doing this optimization right now.
>
>
>> As such, that patch in itself is not the fix. It's a tool for users to fix their code.
>
> But then there's no need to be alarmist. We make the `mutable` fix and just publish a tiny PSA -- if you can't upgrade Qt, here's a workaround for you. And we don't require any other change by anyone else going forward, especially we don't deprecate such an API without good motivation for it?
>
>
> My 2 c,
>
> --
> Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
> KDAB (France) S.A.S., a KDAB Group company
> Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
> KDAB - Trusted Software Excellence
> --
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development
More information about the Development
mailing list