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

Thiago Macieira thiago.macieira at intel.com
Wed Nov 8 01:16:57 CET 2023


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. Or release 
builds for any inline function that didn't get inlined.

Changing of int to qsizetype or qint64 "works" so long as the data actually 
fits the int, which for QVersionNumber is 100% of the cases (I'm not even going 
to say it's "indistinguishable from 100%" because *no one* uses 2.1 billion 
version segments). This problem also only applies to QVersionNumber::size() 
and QVersionNumber::SegmentStorage::size(), because only those two would have 
the same mangling. All the other functions changed by that commit are new 
overloads.

Trying to do the same for QTimer[1] is similar, ignoring the Q_PROPERTY / 
QProperty issues. Because it's exported, we'd need to add a new overload, but 
that just moves the problem one step further. Imagine:

  auto intervalFor(QTimer &t) { return t.interval(); }

If recompiled, this code would start returning qint64 instead of int, but 
would have the same mangling under the IA-64 ABI, which is bad but mostly 
acceptable because it is data-compatible for any timer of less than 24.85 days 
(which is ALL of them today).

This above is inline so it goes back to the original problem of non-inlined 
inline functions. In the case of our comparison types, someone may see that it 
returns auto and decides to write an out-of-line version as:

class MYLIB_EXPORT  Foo
{
    static decltype(Qt::compareThreeWay(0, 0)) compareThreeWay(Foo, Foo);
};

We'd have to document for them not to do this.

This has also just made me realise a different problem: with MSVC, the mangling 
of the function would change. And it's easy to get that problem just by 
exporting one's class, because it always exports inline functions and calls 
that out-of-line copy imported inline function for anything non-trivial:

class MYLIB_EXPORT  Foo
{
    int x;
public:
    auto compare(Foo a, Foo b) { return Qt::compareThreeWay(a.x, b.x); }
    ....
};

So if this user's library is recompiled with a different setting, the ABI 
changes. If the user's user's code mismatches the library, it will fail to 
link.

Therefore, "Almost Never Auto" applies and especially so for return types 
(when used for deducing a type, not for syntactic brevity).

[1] https://codereview.qt-project.org/c/qt/qtbase/+/491119

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Cloud Software Architect - Intel DCAI Cloud Engineering
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5163 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20231107/58f89a08/attachment.bin>


More information about the Development mailing list