On 07.11.23 15:28, Ivan Solovev via Development wrote: > > So, my question is - shoud we support mixing C++17 and C++20 in one binary?
To be clear: This is not about Qt compiled with C++17 used in projects compiled with C++20. This is about one .cpp file being compiled with C++17 and another .cpp file from, broadly speaking, the same cmake target, in C++20 (static builds are different; there, the whole application incl. all "statically-linked libraries", is one executable). What will happen is that the first TU is using a Q*Ordering return type and the second TU is using the std::*_order return type. The linker will them de-duplicate these per-TU inline function bodies and pick one of them. Lets say, for the sake of argument, the C++17 one. Since the two sets of ordering types are not binary compatible, and equivalent states have different numerical values, the result of the call to the function in the C++20 TU will be misinterpreted when it comes from the C++17 function. Of course, the whole thing is UB, so we may not even get so far as a possible misinterpretation. There are several ways to solve this: 1. Ban mixing different C++ versions in the same executable (= cmake target). This is probably the safest. If we allowed this instead, we'd need to review all of our APIs to see whether we have a similar issue already. 2. always use only the Q*Ordering types. Esp. since the numerical values of std::*_ordering and Q*Ordering don't match, this will inject value-mapping code in future-proof idiomatic C++20 code like switch (lhs <=> rhs) { case std::strong_order::less: ~~~; ~~~; } I would very much like to avoid that overhead. 3. make the Q*Ordering types binary compatible with the std ones. If they're binary compatible, then while technically UB (ODR violation) the situation would be very much like any other change to inline API. There are two issues here: First, different std libs have different values for the different states, so we'd need to #ifdef our own enum to what the currently-used stdlib is using. Second, QPartialOrdering was released independent of the C++20 comparison work, in Qt 6.0. So we would need to dissociate the C++20 comparison stuff from it and rename the existing 6.7 Q*Ordering types to, say, Qt:*_ordering, to start with a clean slate. My opinion: - 1 is simplest, but we don't control how users compile our APIs, so someone may still trigger this - 3 is cleanest, therefore preferred: the complexity is on us, but the resulting code is as efficient as can be, regardless of C++17 or C++20. This is how it should be in C++. - I don't like 2. It has it all backwards. Thanks, Marc -- Marc Mutz <marc.m...@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 -- Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development