[Development] Disavowing the Lakos Rule for Q_ASSERT

Thiago Macieira thiago.macieira at intel.com
Mon Aug 26 22:12:55 CEST 2024


On Monday 26 August 2024 12:55:04 GMT-7 Marc Mutz via Development wrote:
> I don't see a proposal for an alternative rule in the above. Please
> provide a) a new rule and b) rationale for it. Bonus points for being
> implementable in a static checker like Clazy or Axivion.

"Q_ASSERT don't affect noexceptness"

Or

"noexcept(false) if you call other, noexcept(false) functions from your code", 
which includes all the pthread cancellation points in glibc. Since qt_assert 
is noexcept, Q_ASSERT is not included. This is very easy to implement with a 
static checker.

We could be more complex, with "Q_ASSERT that check preconditions imply 
noexcept(false) but Q_ASSERT that verify the state of the internal invariant 
against corruption don't". This would not be easy to implement with a static 
checker.

> Background: The Lakos Rule has been the status quo for the last decade
> in C++ and Qt. It is easy to explain and should be pretty
> straight-forward to check. I don't think we as the Qt project are
> qualified to come up with a rule that differs from what std is doing, so
> I strongly suggest not to try. Alternatively, we need _very_ good
> reasons to diverge from what std is doing, not just one developer's hunch.

We don't use exceptions in the first place. Therefore, we don't have to obey 
any rules relating to exceptions that they come up with, nor do their 
constraints necessarily apply to us. And because we don't, qt_assert will 
never be allowed to throw in the first place, so I don't see why we should 
write code that unnecessarily allows for a condition that will never happen.

This hypothetical-probably-never case has real-world consequences for code 
today. The change I am questioning this about is changing the compareEquals() 
and compareThreeWay() functions, which means a search in a container likewise 
becomes noexcept(false). That means an insertion in such an associative 
container may need to use the slower code path to provide exception safety 
even if the moving or creation of the type in question is noexcept.

> Allowing Q_ASSERT to throw into QtTest would be a big step towards
> better testing of failure conditions, something that surely becomes more
> important over time as pressure from legislators on unsafe-memory
> language libraries increases. Any function in-between that's incorrectly
> marked as noexcept prevents that check from working, until it can be
> fixed in the next major release (removing noexcept is BiC). So not only
> do we have _no_ incentive to diverge from std, we also have a rather
> large incentive to keep doing what std is doing.

That's one of those hypothetical scenarios that has never been implemented and 
likely never will. There are other ways to solve the same problem (like 
fork()) that don't involve modifying intermediate code and may work with code 
that was compiled without exception support.

So I am asking that we be pragmatic and cater for the needs we have, not the 
hypothetical needs that have not yet materialised in 15 years.

-- 
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/9a051d0e/attachment.bin>


More information about the Development mailing list