Re: [Development] How qAsConst and qExchange lead to qNN
Marc Mutz via Development wrote: > Sure, a trivial QWidgets program from the mid-90s may still compile and > work in Qt 6, but as soon as said program touches Qt container classes, > it's game over. A lot of the changes to Qt container classes were either driven by you or at least praised by you, so it is really unfair for you to now blame Qt for those changes. Those changes were mainly driven by: * raw performance over backwards compatibility, and sometimes even over API convenience, and * interoperability with new C++ and/or STL features such as std::move, both of which are causes that you have been heavily championing for all this time. Qt could have easily kept old programs just working unmodified. It is you and other "modern C++" promoters that have forced it to break compatibility at everyone else's expense. > Both Boost and C++ itself have a much better track record of keeping > working code working, let alone any random C library. And this is > actually a fair comparison, because we're comparing apples (STL > containers) to apples (Qt containers). The answer to that is that Qt just needs to stop doing incompatible changes. It is time to consider the Qt containers done and retain API and ABI compatibility forever. IMHO, that could and should have happened even with the Qt 4 version. > Let's not kid ourselves thinking Qt is any special here. It isn't. We > mustn't just look at one major release cycle. Qt loses projects at every > new major release, because changes to non-core-competency parts of the > API make porting unnecessarily complicated, so that unmaintained or > understaffed projects[1] cannot muster the strength to be ported. See above. Qt should not be doing major (i.e., API/ABI-incompatible) releases at all anymore. (Heck, you can bump the first digit if you add some great new feature, without necessarily breaking compatibility.) > My goal with qNN is to make porting away _simple_. All that's required > is to s/qNN::/std::/ and be done. No deprecation, no sanity bot, not > even the need for local code knowledge; just simple global textual > replacement. And no regressions, if you first switch to C++NN, and only > then do the replacement. We can even retain the qNN symbols until Qt > requires C++(NN+3), because the qNN headers will be nothing but a long > list of using std::foo; at that time. How about #define q17 std? Or even #define qAsConst std::as_const? If it is really a drop-in replacement as intended, that should work. (And in the unlikely event of a name conflict with user code, #undef can be used as a quick workaround.) > It's not really acceptable that such trivial ports should be subjected > to all the same (or, apparently since it's done in bulk, more > restrictive) requirements than for deprecation of core-competency APIs. > The more so as I must have missed the outcry of developers when we > inflicted > >// Universe A >Qt 1 Qt 2 Qt 3 Qt 4+5 Qt 6 >QGList -> QList -> QPtrList / QValueList -> QList / QVector -> QList >QLinkedList Oh, I did complain about the QList changes in Qt 6. You, on the other hand, have proposed (on 2017-03-18) to just "Kill QList in Qt 6" which would have broken existing application code even more than the change that was implemented. And I was not yet on this list when the Qt 4 changes happened, or I would have complained about those, too. > on an audience that could, instead, have had > >// Universe B >Qt 1 Qt 2-4 Qt 4-5 Qt 6 Qt 6-7 >QGList -> std::vector -> std::vector -> std::vector -> std::vector >CfrontC++98 C++11/14 C++17 C++20/23 But std::vector is much worse than any of the Qt containers above: no implicit sharing, uglier and less complete API, no amortized O(1) prepending optimization. The Qt 5 QList also had efficient random insertions/removals for large structures, a feature that was actually LOST in the Qt 6 version. (Yes, you can explicitly store pointers in the list to simulate the old behavior, but that means less convenient API.) But std::vector never had that feature to begin with. > To hold users, a project must maintain _long-term_ API stability, not > rewrite the container classes for every major release. Indeed. So why have you not supported keeping the Qt 5 QList in Qt 6 then? > So, sorry, but as a user of Qt I'd really like to use those stable STL > classes, if only your volatile APIs let me. I'd rather I had done that > _one_ port between Qt 1 and 2 than all those ports in Qt 1-6. I would rather have kept the Qt containers without constant porting and without losing features (which the STL never had to begin with). Did you know that Qt 3 containers actually had defined behavior on overflows? (An out-of-bounds read would always return 0, which was especially useful for strings.) That was dropped in Qt 4 in the
Re: [Development] How qAsConst and qExchange lead to qNN
Hi all, SCNR taking the proffered bait: On 07.11.22 18:51, Edward Welbourne wrote: > For Qt to remain relevant in the rapidly-evolving C++ landscape, it > needs to change; but one of its strong selling-points has long been its > conservatism in API and ABI, that lets working code keep working. I've not been around for the Qt 1 → Qt 2 port, but I did participate in all of the Qt 2 → Qt 3, Qt 3 → Qt 4, Qt 4 → Qt 5 and Qt 5 → Qt 6 transitions. Speaking with my Qt user hat on, I'm terribly sorry to inform y'all that Qt has largely _failed_ to keep working code working. Sure, a trivial QWidgets program from the mid-90s may still compile and work in Qt 6, but as soon as said program touches Qt container classes, it's game over. Both Boost and C++ itself have a much better track record of keeping working code working, let alone any random C library. And this is actually a fair comparison, because we're comparing apples (STL containers) to apples (Qt containers). Let's not kid ourselves thinking Qt is any special here. It isn't. We mustn't just look at one major release cycle. Qt loses projects at every new major release, because changes to non-core-competency parts of the API make porting unnecessarily complicated, so that unmaintained or understaffed projects[1] cannot muster the strength to be ported. My goal with qNN is to make porting away _simple_. All that's required is to s/qNN::/std::/ and be done. No deprecation, no sanity bot, not even the need for local code knowledge; just simple global textual replacement. And no regressions, if you first switch to C++NN, and only then do the replacement. We can even retain the qNN symbols until Qt requires C++(NN+3), because the qNN headers will be nothing but a long list of using std::foo; at that time. It's not really acceptable that such trivial ports should be subjected to all the same (or, apparently since it's done in bulk, more restrictive) requirements than for deprecation of core-competency APIs. The more so as I must have missed the outcry of developers when we inflicted // Universe A Qt 1 Qt 2 Qt 3 Qt 4+5 Qt 6 QGList -> QList -> QPtrList / QValueList -> QList / QVector -> QList QLinkedList on an audience that could, instead, have had // Universe B Qt 1 Qt 2-4 Qt 4-5 Qt 6 Qt 6-7 QGList -> std::vector -> std::vector -> std::vector -> std::vector CfrontC++98 C++11/14 C++17 C++20/23 To hold users, a project must maintain _long-term_ API stability, not rewrite the container classes for every major release. So, sorry, but as a user of Qt I'd really like to use those stable STL classes, if only your volatile APIs let me. I'd rather I had done that _one_ port between Qt 1 and 2 than all those ports in Qt 1-6. Well, as they say, if 20 years ago was the best time to do the switch, then the next-best time is today[2]. Anyway; to all those who disagree when I say Qt should concentrate on its core competencies and stop meddling with container classes, shared pointers, etc, I say this: which of the two universes above would you rather have lived in these past 30 years? A or B? Be truthful! Because, you see, whenever we phase out some Qt NIH API, we beam a small part of your (and our!) code from Universe A into the Universe B. I _really_ can't understand why anyone would complain. Must be a case of recency bias or something like that... Speaking of the devil, from my pov, qAsConst isn't "small enough" to survive. Fighting off patches that try to make the deleted rvalue overload "do something" is _also_ maintenance work, even if it doesn't result in a code change. Finally, I'll bet my behind (pardon my French) that at some point in the not-too-distant future someone will appear on Gerrit with a patch to change Q_FOREACH to use C++20 ranged-for-with-initializer: #define Q_FOREACH(decl, expr) \ for (const auto _q_foreach_c = expr; decl : _q_foreach_c) And I'd probably approve it, because then that thing can actually just be replaced with the expansion everywhere, and then, finally, be deleted. B Universe, here we come! Thanks, Marc [1] I need qpdfedit once every year to do my taxes, but every year it's getting harder to get the old laptop that still has it installed to run again (yes, I know of VMs) [2] Shamelessly stolen from Isodope (https://youtu.be/ESAaz9v4mSU?t=514) -- Marc Mutz 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
Re: [Development] IMPORTANT: Codereview scheduled maintenance break on Monday 7-Nov 7 am CET
Thiago Macieira (7 November 2022 19:22) requested: > Can you confirm the ED25519 key? > > $ ssh-keygen -l -f /home/tjmaciei/.ssh/known_hosts | grep codereview > 256 SHA256:DwwqNluQyJVkOk+3bFMK6NwWYIGjMnqGP+R0k59e3CY > [codereview.qt-project.org]:29418 (ED25519) I can confirm that; it did indeed appear in another of Jukka's mails, >> ssh_host_ed25519_key >> 256 SHA256:DwwqNluQyJVkOk+3bFMK6NwWYIGjMnqGP+R0k59e3CY (ED25519) Eddy. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] IMPORTANT: Codereview scheduled maintenance break on Monday 7-Nov 7 am CET
On Sunday, 6 November 2022 22:57:52 PST Jukka Jokiniva via Development wrote: > The fingerprint for the RSA key sent by the remote host is > > SHA256:EPuL0PAbNuXXoye7X93ARF7/XALxA5XNAaE3p6M/L3g. Can you confirm the ED25519 key? $ ssh-keygen -l -f /home/tjmaciei/.ssh/known_hosts | grep codereview 256 SHA256:DwwqNluQyJVkOk+3bFMK6NwWYIGjMnqGP+R0k59e3CY [codereview.qt- project.org]:29418 (ED25519) -- Thiago Macieira - thiago.macieira (AT) intel.com Cloud Software Architect - Intel DCAI Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] How qAsConst and qExchange lead to qNN
Volker Hilsheimer (7 November 2022 16:51) wrote: > The open question is whether and when we should deprecate such a > stop-gap 1:1 reimplementations of std functionality. How to deprecate > is now well documented, but the wiki starts with the process of doing > so once we concluded that we shall. It doesn’t give us any guidance > yet on how to come to that conclusion. And, just to be clear, that omission was entirely deliberate. When I wrote [[Deprecation]], I was quite sure we did not have a consensus on the answer to that question, so what I wrote takes no position on the controversy. On the one hand, the benefits of getting rid of old cruft argue for deprecating anything for which there is now a better way to do whatever it was there for; on the other hand, disruption to users of Qt is unwelcome, arguing for only deprecating anything when its use is actually apt to cause harm (e.g. the old API incorporates a design bug). For Qt to remain relevant in the rapidly-evolving C++ landscape, it needs to change; but one of its strong selling-points has long been its conservatism in API and ABI, that lets working code keep working. There is thus an inevitable tension between "move forward, leaving the past behind" and "if it ain't broke, don't 'fix' it", Eddy. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] How qAsConst and qExchange lead to qNN
> On 4 Nov 2022, at 16:00, Marc Mutz via Development > wrote: > > Hi, > > After getting my head washed by Volker, lemme provide background on > these two functions. Thanks for the context, Marc! > TL;DR: we created real maintenance and porting problems by not removing > stop-gap functionality in a timely fashion, qNN presented as a way to > ensure this won't happen again. > > Both qAsConst and qExchange are 1:1 reimplementations of std > functionality we couldn't rely on back then (as_const is C++17 and > exchange is C++14), so they're exactly equivalent to the std versions. > Or were, when they were added. > > Neither std::as_const nor qAsConst have changed, so the replacement is > easy: s/qAsConst/std::as_const/. It cannot not compile because qAsConst > comes from qglobal.h and that transitively includes . This is > what was intended from the get-go: The open question is whether and when we should deprecate such a stop-gap 1:1 reimplementations of std functionality. How to deprecate is now well documented, but the wiki starts with the process of doing so once we concluded that we shall. It doesn’t give us any guidance yet on how to come to that conclusion. As qAsConst has shown, it is of course useful and pragmatic for us to introduce certain functionality before the respective C++ standard is generally available to us. Let’s then assume - for the sake of argument - that we might be able to require a new standard 2 years after all generally available compilers fully implement it (C++20 has perhaps reached that point [1] if we ignore Apple clang’s limping behind on library features, so let’s say 2024). Then there’ll likely be a lot of code in Qt that is using our temporary implementation. Again, qAsConst is a good example. [1] https://en.cppreference.com/w/cpp/compiler_support The questions is now what we do. Replacing all qAsConst with std::as_const is mechanically straight forward, also thanks to the tooling that Marc and others have been building for that purpose. So as long as we follow the proposed rules, then making the change as such not the problem. And neither is reviewing - with well-tested tooling, reviewing every line of diff produced adds little value. However, such a changes will touch a lot of code, across all repositories. And that introduces conflicts when cherry-picking changes back to stable branches (and it messes up the git blame history, which for one-liners is perhaps rarely an issue). If we consider the s/count/size, s/qAsConst/std::as_const, s/QStringLiteral/u””_s, … replacement activities, then each of them might not be a big issue, but the sum of lines changed by all of them together quickly makes this become a source of bother and discontent. To a certain degree, the argument is the same as for making coding-style fixes: we don’t, unless we touch the respective code anyway. That’s not an entirely fair comparison, because we do have to maintain our Qt replacements for as long as they get used in Qt. With qAsConst, maintaining 4 lines of code would perhaps have been acceptable if it saved us that noise. With the 9 lines of qExchange, Marc has already pointed out that we have diverged from std. If we consider std::span or std::expected - we clearly don’t want to drag those implementations around with us for longer than absolutely necessary. So, there probably can’t be a single rule that fits every situation. And removing something from everyone’s toolbox, like qAsConst, might anyway deserve creating a bit more awareness. Hence, a suggestion: When it’s time to phase out one of our own qNN implementations, then 1) propose the change here first to raise awareness, and to give people time to ask questions and/or raise objections Even if the people doing the work all agree, a lot of maintainers and contributors will still be impacted (at least by the tool being removed). The proposal should come with some data about how prevalent the usage of the relevant construct is in Qt. It makes a difference whether we’d have to touch a few dozen lines, or several hundred to remove all usage. 2) If possible, add a warning to the sanity bot so that no new usage is added This is trivial in some cases, not so trivial in others. Rationale: For changes that impact a larger amount of code, there’ll be plenty of time between those changes getting merged, and the old Qt-implementation ultimately getting removed or fully deprecated (which we can’t/shouldn’t do while we still have usage in Qt itself). For example, we now have some qAsConst back in the qtbase code. Whether we then do a bulk replacement in Qt, or whether we just stop using old stuff in new code and phase it out over time as we touch code (until here’s perhaps little enough left to make a bulk change), depends on the discussion. If we do make a bulk change, then making that change in stable branches to avoid cherry-picking conflicts would probably be ok as well
Re: [Development] Monthly CI maintenance break - November (Mon 7th Nov 2022)
This is now DONE From: Ville-Pekka Karhu Sent: Monday, November 7, 2022 08:03 To: Qt development mailing list Subject: Re: Monthly CI maintenance break - November (Mon 7th Nov 2022) This maintenance break starts NOW From: Ville-Pekka Karhu Sent: Monday, October 31, 2022 13:11 To: Qt development mailing list Subject: Monthly CI maintenance break - November (Mon 7th Nov 2022) Hi all! We’ll have our scheduled maintenance break on next Monday (7th of November). We’ll begin our work at 6:00 UTC and you can prepare for 6 hours of CI not working. Br, VP ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] C++20 comparisons @ Qt (was: Re: C++20 @ Qt)
On 04.11.22 12:13, Ulf Hermann via Development wrote: >> One thing I haven't understood about the ordering problem is why we >> cannot just define our "invalid" values to always be < any valid one and >> equal to other invalid ones. This way we get at least weak ordering for >> all our types and we're done. Marc Mutz via Development (4 November 2022 16:15) > That's what we're currently doing, yes. At least for QDateTime. One factor in why I think partial order is probably a good choice is that invalid QDateTimes are a bit more complicated than, say, null QStrings; there is a null QDateTime, but you can also get an invalid one by asking for a time that doesn't exist in the zone (overtly for spec = TimeZone, implicitly for spec = LocalTime) in use, when folk moved their clocks forward over that time in the given zone, typically in spring at the start of DST. These QDateTime instances, although invalid, do have a toMSecsSinceEpoch() that's suitable to passing to fromMSecsSinceEpoch() to reconstruct a valid date-time that's not what you originally asked for but is close by. See [0] for my attempt to do better than that kludge. [0] https://codereview.qt-project.org/c/qt/qtbase/+/308729/25 > For QString, we have that isNull() compares equal to empty. Which makes a fair amount of sense, IMO. Default-constructed string is empty. > ... that prompted > me to remember QOperatingSystemVersion, where we really, genuinely > have several sets of values where elements from different sets are not > ordered (Win10 There, partial_ordering is consistent with the current implementation. Good example. > We don't _need_ to make invalid values unordered, but it would be the > mathematically correct thing to do. ... in some cases, at least. For containers, like QString, null-is-empty makes perfect mathematical sense, for example; the empty set is the "null" set (and relation, and function), in so many senses. Indeed, IIRC, the first teacher to introduce me to it used a slashed-zero called "null" to denote it. > We removed QVariant::op< because of these problems. partial_ordering > would allow [us] to bring it back. Albeit "whether we *should*" remains a separate story. >> There may be types where existing operator< work differently (*cough* >> QTypeRevision), but that just means we need to emulate that same >> behavior with the new operators. > Without having looked at QTypeRevision, I agree in general. Certainly in the first instance we should match existing behaviour as closely as possible with the new operators; but partial ordering does present (once we're fully migrated to C++20) a new option that may be a good choice for some types. I don't advocate a blanket "do this everywhere"; but there may well be types for which it makes sense. >> Indeed the NaN behavior has always been a pain to deal with every time >> I've encountered it. If we have a chance to avoid it, we should. >> >> What is the downside of such an approach? > The (potential) downside is that it's arbitrary and classes might behave > inconsistently (one sorts invalid before valid ones, the other vice > versa). It may also be a bit more work to document (unless we choose not > to mention that little detail). Or we can't reap any future tool support > that might be developed for partial_ordering (sanitizers, etc). The NaN behaviour is a necessary escape from worse surprises; for example, "if x < 0 and y < 0, then x * y > 0" - except that if you make NaN < 0 that'll fail. Of course, having the NaN drop into the else branch of an if (x < 0) is apt to have it mistakenly presumed to be >= 0, when it also isn't that. Still, with the language now actually supporting partial order, we get the option of using it and at least giving diligent programmers the chance to handle such cases gracefully' and by overtly making some orderings partial, alert them to the need to. The question remains: for which of our types will it actually make sense to have a partial ordering ? I trust those closest to the code to have a clue, in each instance. Eddy. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] Using '#pragma once' instead of include guards?
On Mon, 10 Oct 2022 at 13:13, Hasselmann Mathias wrote: > > I am surprised by the question: "It's non-standard and it's behavior is > undefined" actually should be enough to avoid such feature. > > Actually if a reliable implementation of "#pragma once" would be > possible, that feature would have been included in the C++ standard for > a long time already, wouldn't it? Oh, there is a reliable implementation, no problem there. :D It's called "hash the file contents". Various implementations have different modes of operation where they desperately try to avoid doing that, or do that just partially. The last time standardizing a "#once" was discussed in the standard committee was 2012, and compiler vendors' feedback killed the idea dead, and it hasn't come back since. We have spent our energy standardizing modules instead. The C committee has been recently considering standardizing a "#once". It has been attempted to make them aware of the compiler vendor feedback on the C++ side of things. It will be a glorious day when we stop doing textual inclusion, and don't need to talk about its myriad problems any more. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] IMPORTANT: Codereview scheduled maintenance break on Monday 7-Nov 7 am CET
I had a typo on the port number. Of course the host key update affects the port 28418, where the Gerrit is running. Not 28419, like I stated earlier. Sorry for the confusion. --Jukka From: Development on behalf of Jukka Jokiniva via Development Date: Monday, 7. November 2022 at 9.00 To: development@qt-project.org Subject: [Development] IMPORTANT: Codereview scheduled maintenance break on Monday 7-Nov 7 am CET Maintenance break is now over. IMPORTANT: Server host keys have been updated. When doing a git command you might get warning like: @@@ @WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the RSA key sent by the remote host is SHA256:EPuL0PAbNuXXoye7X93ARF7/XALxA5XNAaE3p6M/L3g. Please contact your system administrator. This is expected. To fix this see the instructions in the bottom of this email chain. --Jukka Jokiniva, Gerrit Admin From: Development on behalf of Jukka Jokiniva via Development Date: Monday, 7. November 2022 at 8.00 To: development@qt-project.org Subject: [Development] Reminder: Codereview scheduled maintenance break on Monday 7-Nov 7 am CET Gerrit maintenance break will start in 5 minutes. From: Development on behalf of Jukka Jokiniva via Development Date: Tuesday, 1. November 2022 at 13.04 To: development@qt-project.org Subject: [Development] Codereview scheduled maintenance break on Monday 7-Nov 7 am CET Hi all, There will be a maintenance break on the codereview.qt-project.org on Monday 7-Nov 7:00 am – 9:00 am CET. Gerrit version will be upgraded to 3.5.3. IMPORTANT: Server host keys on port 29419 will be updated to support modern algorithms. Also the existing RSA key will be updated to a longer key size. After the change the git commands may fail with errors about mismatched or changed host keys or host identification. To fix this remove locally the old known host key (on Linux based remove the corresponding line in ~/.ssh/known_hosts -file) and verify the new one (git will prompt for verification). Here are the finger prints of the keys that will applied on 7-Nov: ssh_host_ecdsa_384_key 384 SHA256:yMnqjnsJU0y6kfiyQQu8pYNGPFE7av5QxbeLdjTKNmk (ECDSA) ssh_host_ecdsa_521_key 521 SHA256:kytLsqmLdG1KXLO/s3OxOajTYqf1+n7+YqqbOUzNbtE (ECDSA) ssh_host_ecdsa_key 256 SHA256:El3+EYlXAGylCVo/Y/WYzPg7tS4fjejkepO1JVXUkb0 (ECDSA) ssh_host_ed25519_key 256 SHA256:DwwqNluQyJVkOk+3bFMK6NwWYIGjMnqGP+R0k59e3CY (ED25519) ssh_host_rsa_key 4096 SHA256:EPuL0PAbNuXXoye7X93ARF7/XALxA5XNAaE3p6M/L3g (RSA) --Jukka Jokiniva, Gerrit Admin ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development