On 26.08.24 22:12, Thiago Macieira wrote:
> 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.

If we make the distinction between Q_ASSERT-as-precondition-check and 
Q_ASSERT-as-internal-invariant/state-check (with a new macro 
name/names), then I can agree to that. Note, however, that the example 
that sparked this discussion (View::slice(int, int)) remains 
noexcept(false) under this rule, too. Ditto op==(It, It).

I have tried to adjust 
https://wiki.qt.io/Things_To_Look_Out_For_In_Reviews#noexcept 
accordingly. For offline reader convenience, it currently reads:

>     Only functions that cannot fail to meet their post-conditions can be 
> noexcept. Failure to meet post-conditions can stem from a variety of reasons, 
> including a) having preconditions that are not met, b) calling a Posix 
> Cancellation Point or another noexcept(false) function (which may prematurely 
> end the function), or c) allocating memory or other resources (file handles, 
> mutexes). Rationale: This is the Lakos Rule (latest version: 
> https://wg21.link/p2861). We should track what the standard does and not 
> invent rules of our own. Specifically for preconditions, there are vague 
> plans to make them testable from QtTest by making Q_ASSERT() throw an 
> exception instead of calling abort() on failure; any noexcept function 
> in-between will cause this to not work. Specifically for (b), some Posix 
> systems implement thread cancellation by throwing an exception-like object to 
> unwind the stack (e.g. glibc-based ones). Such exceptions must not be 
> swallowed by user code (incl. Qt code) lest thread cancellations ends in 
> std::terminate().
>         Exception: Like the std smart pointers, our smart pointers 
> operator*() may also be noexcept, but then they must not contain a 
> Q_ASSERT(). Rationale: When in Rome^WC++, do as the Romans do^W^Wstd does.
>         Distinguish Q_ASSERT()s that check for precondition violations (= 
> user is responsible) and those that check internal state/invariants in our 
> code (= we are responsible). The former requires the function containing them 
> to be noexcept(false), the latter doesn't. Rationale: The Lakos Rule is about 
> contract violations, not about internal consistency checks. If internal 
> consistency is found to be in disarray, recovery is likely impossible. If a 
> call contract is violated, OTOH, that may be very much recoverable, because 
> it's detected before "something bad" may happen. We'll hopefully get separate 
> macros for the two, but for now, be aware of the two different use cases of 
> assertions.
> 


Thanks,
Marc

-- 
Marc Mutz <marc.m...@qt.io> (he/his)
Principal Software Engineer

The Qt Company
Erich-Thilo-Str. 10 12489
Berlin, Germany
www.qt.io

Geschäftsführer: Mika Pälsi, Juha Varelius, Jouni Lintunen
Sitz der Gesellschaft: Berlin,
Registergericht: Amtsgericht Charlottenburg,
HRB 144331 B

-- 
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to