[Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)

Marc Mutz marc.mutz at qt.io
Wed Nov 8 09:38:32 CET 2023


Let's not mix up topics here...

1/ We're not responsible for the ABI of third-party libraries. As long as 
we document that the return type of a non-exported inline functions 
changes, then it's SEP if someone else writes code that ties their ABI 
to the result type of such functions.

We're only responsible for our own ABIs. And _we_ know not to export 
functions that can change return type.

That leaves 2/ the mythical "merge of inline functions from different 
libraries" and 3/ "mixing of C++ versions within the same executable" 
situations.

I agree that the latter is a problem; I stated as much in my previous 
email, and gave (1) and (3) as solutions.

But I still don't see how the former is a problem, or, if it is, why (3)
(BC between {std,Qt}::_ordering) doesn't fix it, too.

On 08.11.23 01:16, Thiago Macieira wrote:
> On Tuesday, 7 November 2023 13:34:04 PST Marc Mutz via Development wrote:
>>> Yes. Remember that "one binary" is the process as loaded into memory,
>>> including all the libraries. Depending on compilation modes, inline
>>> functions may be merged from multiple independent libraries at runtime.
>>
>> Sorry, but [citation needed]. This goes against _everything_ I know and,
>> more importantly, everything we've been doing the last decades, incl.
>> your own https://codereview.qt-project.org/c/qt/qtbase/+/389682
> 
> Any debug build that isn't using -fvisibility-inlines-hidden.

Does this apply only to inline methods of exported classes, or to any 
inline function at namespace scope, too? Anyway, I thought that Qt is 
always compiled with -fvisibility-inlines-hidden? Do our BC guarantees 
even apply if they're not? E.g. how can we remove an inline function and 
have it be BC? In the specific case of QVersionNumber::size(): the 
mangling changed on MSVC, so we removed the function and replaced it 
with another one. That was ok, though, since QVN is _not_ exported, so 
each user contains its own copy of the function.

Case in point: We didn't add a new overload of resize() 
https://codereview.qt-project.org/c/qt/qtbase/+/389682/5/src/corelib/tools/qversionnumber.h#175 
to keep old source working, we _replaced_ the function. If what you say 
is true, then that would be BiC, because existing users of the function 
would not find the new function (with a different mangled name). This is 
safe precisely because non-exported inline functions are _not_ magically 
called from other libraries. This is a cornerstone of our API evolution.

> Or release
> builds for any inline function that didn't get inlined.

[citation needed]

AFAIK, if a non-exported inline function isn't inlined, then each TU 
contains an out-of-line copy of the function and the (static) linker 
will de-duplicate them all into a single one. That's per executable 
("cmake target", for dynamic linking), and means that each executable 
contains its own independent copy of the code.

Call me daft, but I still don't see it.

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