[Development] Disavowing the Lakos Rule for Q_ASSERT

Thiago Macieira thiago.macieira at intel.com
Mon Aug 26 22:28:34 CEST 2024


On Monday 26 August 2024 12:59:54 GMT-7 Marc Mutz via Development wrote:
> Part of why I'm sympathetic to the assertions throw mantra is that I
> used it very successfully in Kleopatra way back when. We could easily
> take the exception's what() and report back over the UI server channel
> that an assertion happened and the client would show a message box with
> the assertion details, copyable from a QMessageBox into a bugreport.
> T'was a boon for testing.

Only developers would be interested in seeing exception names. Regular users 
won't understand what that exception means and will just be confused.

I am also vehemently against catching exceptions you don't have a recovery 
code path for. That destroys the stack trace and state that would have helped 
the developer understand and actually fix the problem.

I suppose it's possible someone will use preconditions for recoverable 
conditions, but I've never seen that even proposed, for any API. More 
importantly, for the cases we have at hand, like:

        static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs,
                                                          const Iterator &rhs) 
noexcept
        {
            Q_ASSERT(lhs.item.d == rhs.item.d);
            return Qt::compareThreeWay(lhs.item.i, rhs.item.i);
        }

The most likely reason for violating this precondition is that the caller is 
already corrupt and totally lost. I don't see how it could recover.

Another example is:
QUuid QCborValue::toUuid(const QUuid &defaultValue) const
{
    if (!container || !isUuid() || container->elements.size() != 2)
        return defaultValue;

    Q_ASSERT(n == -1);
    const ByteData *byteData = container->byteData(1);
    if (!byteData)
        return defaultValue; // UUIDs must always be 16 bytes, so this must be 
invalid

    return QUuid::fromRfc4122(byteData->asByteArrayView());
}

This is verifying an internal invariant state, not a precondition. The only 
two reasons this assertion would trigger are a buggy implementation or 
corrupted memory. Neither of which you can recover from with C++ code.

[This code isn't noexcept because QUuid::fromRfc4122 wasn't noexcept when it 
was written]

-- 
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/20240826/97ff4c47/attachment-0001.bin>


More information about the Development mailing list