[Development] QVariant and types with throwing dtors
Volker Hilsheimer
volker.hilsheimer at qt.io
Wed Aug 21 15:34:15 CEST 2024
> On 9 Aug 2024, at 17:52, Thiago Macieira <thiago.macieira at intel.com> wrote:
>
> On Friday 9 August 2024 01:46:02 GMT-7 Fabian Kosmale via Development wrote:
>> 1. Don't do anything; that's the behavior we have since at least Qt 5.
>> If the dtor doesn't actually throw, everything is fine; if it does
>> throw, we're calling std::terminate. Might lead to unexpected results,
>> but doing nothing obviously doesn't break any existing code. It is
>> however inconsistent with other types.
>> 2. Warn, but still accept such types [2]. I've implemented that in
>> https://codereview.qt-project.org/c/qt/qtbase/+/580560. Anyone one
>> stores a type with a throwing dtor would get a warning, but everything
>> still compiles. The warning can however be considered spurious if the
>> author knows that given their usage, the type would never throw.
>> 3. Reject such types at compile time. That would be consistent with
>> other types, but might break existing code, even code that works
>> perfectly fine because it can never actually throw.
>>
>> I'm leaning towards either 1 (nobody ever reported a bug about QVariant
>> calling std::terminate so far), or 2 ( more consistent with our policy
>> for containers, highlights that such usage is potentially dangerous).
>
> I think we're fine just leaving it as-is, case 1. As you said, no one has
> reported a problem and I doubt they ever will. We cannot make QVariant
> destructor throwing, because that would in turn make QVariantList impossible.
> For that matter, std::any's destructor is also noexcept.
>
> One problem with a warning or rejecting (cases 2 and 3) is that we have to
> provide a way for people to fix it. If their type does indeed need a throwing
> destructor, then they can't make it noexcept. They can't wrap it in something
> else (is-a or has-a) because this is QVariant and the actual type matters. We
> can provide a macro to return to current state for code that knows what it is
> doing, but that increases our maintenance burden for something that has never
> been a problem.
>
> You also can't completely accomplish this at compile time, because you can
> create a QVariant payload with just a metatype:
>
> QVariant v(QMetaType::fromType<ThrowingDestructor>());
>
> As you're not proposing rejecting throwing-destructor-types from QMetaType, we
> can't compile-time reject the above. We'd need to do it at runtime, at the
> expense of another bit extracted into the QMTI, and impact everyone else's
> runtime to check that bit and warn or reject. We'd probably not do the runtime
> checking at all, because of the side effect and because the construction of the
> user code as above could mean the developer never sees the problem until
> releasing.
>
> I don't think it's worth it.
Agree with Thiago here. The problem is a bit academic, and doesn’t seem large enough to justify the complexity required in making a bullet-proof solution.
Volker
More information about the Development
mailing list