[Development] On Removing Public Undocumented/\internal APIs

Marc Mutz marc.mutz at qt.io
Mon Mar 4 10:57:18 CET 2024


Hi,

TL;DR:
- Treat all APIs not clearly marked as private (private access, *Private
   namespace or "We mean it!" comment) as public, in particular keep SC/BC
   and deprecate before remove.
- Avoid adding APIs that aren't clearly private or public in the future.

I'd like to start a discussion around the expectations of Qt users 
w.r.t. public (in the C++ sense) API which is either not documented or 
"documented" as \internal. I put "documented" in quotes because the 
\internal "documentation" is of course not visible on doc.qt.io.

First observation: To users, an \internal API is indistinguishable from 
an undocumented one.

Well, unless we seriously expect users to verify every result of their 
IDE's auto completion to be documented, undocumented or \internal in the 
Qt source code.

Second observation: Such function _are_ visible in the IDE's auto 
completion, and in the installed header files, though.

The question that came up in 6.7 API reviews (repeatedly¹, for some 
reason (is there some spring-cleaning going on I'm not aware of?) is, 
then: is it ok to remove such functions? If it's ok to do so, do we need 
a [ChangeLog][Potentially Source-Incompatible Changes]. And if not, do 
we deprecate it?

¹ Off the top of my head: QString::isSimpleText(), QPen::data_ptr(), 
QDeferredDeleteEvent

For reference, when I was still on the other side of the pond (ie. a Qt 
user), I remember arguing: "well, X is not documented, but it's public, 
so go ahead and use it", so I'm naturally tending toward classifying 
such removals as QUIP-6 SiC Type B, ie. unacceptable. Other developers 
think nothing of it, approving such changes even without an accompanying 
[ChangeLog].

Third observation: we do not document all functions we consider public, 
either.

There are omissions like SMFs, which are addressed by recent QDoc 
changes that cause SMFs to be automatically documented. There are 
omissions like certain function (overloads) forgotten to be documented 
(e.g. on QAtomic or, if memory serves me well, QSharedPointer). And I 
believe we also have some uses of \internal which are to be interpreted 
as "omit from documentation", probably because the author didn't feel 
the function deserved documentation (dtors, e.g.).

I challenge everybody who thinks it's OK to remove APIs that are not 
_visible_ marked as non-public (Qt*Private namespace, _p.h or other file 
with "We mean it." comment) to explain to me how a users should 
understand, given the three observations above whether a function, type 
or macro name suggested by an IDEs auto completion or by looking at the 
header file is supposed to be treated as "undocumented (forgotten)", 
"undocumented (your guess is as good as mine), and "documented \internal".

I would suggest that we treat any entity defined in a header file that 
is not in a *Private namespace or under the umbrella of an "We mean it!" 
commant, in short: anything that isn't _visible_ as non-public API _from 
the header file_, as semi-public, and apply the same rules as for public 
API: keep BC/SC, deprecate first, remove second, and adjust QUIP-6 
accordingly.

At the same time, we should make sure that we don't accept such 
semi-public APIs going forward anymore.

In most cases, this isn't really any extra work for us, but it will help 
both current users of such APIs (they get a warning with suggested 
replacements instead of an out-of-the-blue linker error) and future 
users of our API to easily distinguish between public and private APIs.

Opinions? Comments?

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at qt.io>
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


More information about the Development mailing list