[Development] QVariant and types with throwing dtors
Thiago Macieira
thiago.macieira at intel.com
Fri Aug 9 17:52:28 CEST 2024
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.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Principal Engineer - Intel DCAI Platform & System Engineering
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5152 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20240809/96333039/attachment.bin>
More information about the Development
mailing list