The question has arisen when we had an argument at work about what
reentrancy Qt style actually means. After no conclusion was reached I've
started googling and asking LLMs and realized it's never explained well
anywhere so I am going to list what I think really needs to be corrected.

The way that the docs spell the concept leaves too much for interpretation:

Throughout the documentation, the terms reentrant and thread-safe are used
to mark classes and functions to indicate how they can be used in
multithread applications:

In truth, usually, documentation says something along the lines of:

Note: All functions in this class are reentrant with the following
exceptions:

Note how this doesn't explicitly mark a class at all. This leaves room for
interpretation which section of the reentrancy docs is relevant: the class
one or the function one. It only deals with class functions, not class
data. This is an important distinction.

Then, in the function section we have:

A reentrant function can also be called simultaneously from multiple
threads, but only if each invocation uses its own data.

There's an argument to be made that an invocation through const instance is
using "its own data" as long as the actual data is separate. For example,
QLocale::toDouble provides a separate string and a separate ok pointer to
be used through a static instance in a const function. You'd naturally
expect such an invocation to be safe. There's also the fact that a
significant portion of the C++ devs don't really think of the "this"
pointer as a part of the function signature.

I feel like this part of the documentation really needs rewording and
explicitly mentioning that "its own data" means using static instance
doesn't qualify as reentrant use case.

Then we get to the really confusing part and this one I think is a critical
issue: a lot of devs treat const methods as safe when nothing else is
modifying the class data at the same time. This ties into reentrancy
because of "well, the instance is const so..."

I had a conversation with Thiago and Giuseppe on Slack and heard two
different opinions on the issue:

Thiago: "lazy init does defeat reentrancy"

Giuseppe: "formally speaking Qt does *not* guarantee that, on a class
marked reentrant, you can safely call const functions on the same object"

I cannot see how these two statements can be reconciled under the same
interpretation of reentrancy. But this goes even deeper than this.

Upon further conversation it turned out that while Qt doesn't guarantee
pure const operation being safe, it usually is and people tend to rely on
that without it ever being clarified anywhere in the respective classes
documentation. E.g. QRegularExpression which even clazy recommends to use
as an unprotected static instance despite the only guarantee that the docs
of the class provide being reentrancy which should *not* allow such a use
case under the wording Giuseppe provided.

My issue is that if it's not guaranteed and being constantly relied on it
*has* to be documented both in each class case separately and have a
section with exceptions in reentrancy and thread safety page.

This situation untenable: people are conditioned to treat const as safe by
standard library, clazy and advice online where in fact there are
exceptions to that rule that are not documented anywhere and can easily
result in UB without anyone being the wiser.

Case in point QCollator::compare which seemingly does unprotected lazy
initialization inside a const function. It may be a bug but even Giuseppe
had stated that Qt doesn't guarantee such use case and exceptions are
possible here and there despite it "generally" being safe.

I cannot reconcile how a framework can allow this ambiguity to exist
without ever clarifying which classes are actually safe to use through
consts simultaneously and which ones are not while its developers being
aware of the general sentiment and how it's actually being treated. TLDR:
please, fix documentation and make it harder to misread it. Also clarify
what is const safe and what isn't.
-- 
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to