Re: [Development] QtCS 2017 QtCore sessions
On 2017-12-04 21:05, Ville Voutilainen wrote: Same goes for semantics. In fact, I'm _mainly_ concerned with semantics. Different method naming is trivially fixed by tooling these days, as long as the semantics are the same. As a trivial example: qAsConst, like std::as_const, has the rvalue overload `= delete`d. For Qt containers, and most STL ones, too, with the notable exceptions of QVLA and std::array, it would make sense to allow the rvalue overload, but return a new object moved from the original. Then lifetime extension would kick in and for (auto : qAsConst(funReturningQVector())) would be safe, albeit less efficient as the alternative. But getting rid of qAsConst would then be much harder, since std::as_const does not have an overload for rvalues, so the above code would need to be transformed into const auto uniq = funReturningQVector(); for (auto : uniq) which is what you're forced to write today already, thanks to the lack of the rvalue overload. As an aside: it also makes the API easier to abuse (by allowing std::array and QVLA rvalues). So, IMNSHO, it's better to not add the rvalue overload to qAsConst, but keep it `= delete`d, thereby maintaining semantic one-to-one-ness with std::as_const, in turn making tools to perform the rewrite trivial (in this case, as easy as `s/qAsConst/std::as_const/g`). Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 4 December 2017 at 21:29, Allan Sandfeld Jensenwrote: >> > I believe the name "optional" comes from Haskell and Java where it >> > appeared >> > first. The standard library only imports things that are already industry >> > standard, and once there were several implementations of optional out >> > there, they started to pull one in. They just didn't manage to write it >> > without using C++17'isms. >> >> std::optional has no fundamental c++17isms in it, and can be written >> without any problem in C++11 code. >> I maintain optional in libstdc++, in case you wonder on what basis I'm >> making that statement. > I know it can be written with C++11. I have both seen it, and done it myself. > I was just noting the C++17 version takes advantage of C++17 (which makes > sense). I did not mean to imply you couldn't or hadn't. I am sorry if I > formulated that wrongly. Right; stylistically, the C++17 specification uses C++17 facilities when convenient - that has nothing to do with what the committee "manages" to do or not. For optional, it uses, for example, the _v trait-value variable templates, which are C++17, but are perfectly possible to express with the longer-hand form with ::value. Beyond those, optional doesn't do anything C++17-specific (and was in fact implemented *and specified* in terms of C++14 when it was experimental::optional, and even there, the only C++14 facility it used was relaxed constexpr, but again, those things can be written with C++11 constexpr). Under the general as-if rule, implementations can and do implement optional with equivalent facilities that were there since well before C++17. >> The standard library imports a whole host of things that aren't always >> industry standards. but it imports things only when there's a proposal >> to import something. > > For this part I was refering call for proposals http://cplusplus.github.io/ > LWG/call-for-library-proposals.html which says it strongly prefers things > based on existing practice. Yes, *prefers*, but doesn't *require*. Even the ISO guideline of standardizing existing practice is a recommendation, not a hard requirement. > Anyway. I was just taking offense at Marc's claims that Qt was "stealing from > C++" by adopting similar compatible ideas as the standard library, but made > available for our supported platforms in our time frame. It made little sense > to me, as you might as well argue Qt is stealing from Windows and Mac, by > making a cross-platform toolkit implementing their established practices. I think Marc's concern is adopting e.g. an optional-like type and giving it a *completely* different interface because we prefer camelNames to std_like_names, which is migration-wise, generic-programming-wise and interoperability-wise a complete dead end. This leads to a discussion we need to have at some point, which is that if we write a Qt facility that's expected (no expected-related puns intended) to have an equivalent facility in the standard, we should give such facilities a standard-like interface with standard-like naming, instead of following our usual naming conventions. Same goes for semantics. Which brings us back to the discussion on constexpr on QStringView - it hurts migration and interoperability if string_view has constexpr operations that are not constexpr on QStringView. Having said that, there are nuances there, like *how much* it hurts and what kind of migration/interoperability. General design principles can have engineering exceptions, when the rationale for such is sufficient. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Montag, 4. Dezember 2017 15:30:49 CET Ville Voutilainen wrote: > On 4 December 2017 at 16:20, Allan Sandfeld Jensenwrote: > > On Montag, 4. Dezember 2017 15:00:53 CET Marc Mutz wrote: > >> Ah, well, yes. Nothing truly originates in C++, true. But, IIRC, the > >> Haskell name is maybe. So why is it QOptional and not QMaybe? Because > >> the C++ interface is used as the basis, not something from Haskell. > > > > I believe the name "optional" comes from Haskell and Java where it > > appeared > > first. The standard library only imports things that are already industry > > standard, and once there were several implementations of optional out > > there, they started to pull one in. They just didn't manage to write it > > without using C++17'isms. > > std::optional has no fundamental c++17isms in it, and can be written > without any problem in C++11 code. > I maintain optional in libstdc++, in case you wonder on what basis I'm > making that statement. I know it can be written with C++11. I have both seen it, and done it myself. I was just noting the C++17 version takes advantage of C++17 (which makes sense). I did not mean to imply you couldn't or hadn't. I am sorry if I formulated that wrongly. > The standard library imports a whole host of things that aren't always > industry standards. but it imports things only when there's a proposal > to import something. For this part I was refering call for proposals http://cplusplus.github.io/ LWG/call-for-library-proposals.html which says it strongly prefers things based on existing practice. Anyway. I was just taking offense at Marc's claims that Qt was "stealing from C++" by adopting similar compatible ideas as the standard library, but made available for our supported platforms in our time frame. It made little sense to me, as you might as well argue Qt is stealing from Windows and Mac, by making a cross-platform toolkit implementing their established practices. Best regards 'Allan ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Monday, 4 December 2017 06:00:53 PST Marc Mutz wrote: > Ah, well, yes. Nothing truly originates in C++, true. But, IIRC, the > Haskell name is maybe. So why is it QOptional and not QMaybe? Because > the C++ interface is used as the basis, not something from Haskell. FYI, I wrote QMaybe some 9 to 10 years ago, when D-Bus was discussing having maybe types. https://dbus.freedesktop.org/doc/dbus-specification.html#idm423, see "Reserved for a 'maybe' type compatible with the one in GVariant, and must not appear in signatures used on D-Bus until specified here" Since it didn't happen there, it didn't happen for us either. > Alex Stepanov also agrees that vector may not have been his wisest > naming choice for a dynamic array container, but it's still QVector, and > not QArray, after all And QList is not a linked list. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
04.12.2017, 17:31, "Ville Voutilainen": > On 4 December 2017 at 16:20, Allan Sandfeld Jensen wrote: >> On Montag, 4. Dezember 2017 15:00:53 CET Marc Mutz wrote: >>> Ah, well, yes. Nothing truly originates in C++, true. But, IIRC, the >>> Haskell name is maybe. So why is it QOptional and not QMaybe? Because >>> the C++ interface is used as the basis, not something from Haskell. >> >> I believe the name "optional" comes from Haskell and Java where it appeared >> first. The standard library only imports things that are already industry >> standard, and once there were several implementations of optional out there, >> they started to pull one in. They just didn't manage to write it without >> using >> C++17'isms. > > std::optional has no fundamental c++17isms in it, and can be written > without any problem in C++11 code. > I maintain optional in libstdc++, in case you wonder on what basis I'm > making that statement. > The standard library imports a whole host of things that aren't always > industry standards, but > it imports things only when there's a proposal to import something. See also https://github.com/akrzemi1/Optional/blob/master/optional.hpp > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 4 December 2017 at 16:20, Allan Sandfeld Jensenwrote: > On Montag, 4. Dezember 2017 15:00:53 CET Marc Mutz wrote: >> >> Ah, well, yes. Nothing truly originates in C++, true. But, IIRC, the >> Haskell name is maybe. So why is it QOptional and not QMaybe? Because >> the C++ interface is used as the basis, not something from Haskell. >> > > I believe the name "optional" comes from Haskell and Java where it appeared > first. The standard library only imports things that are already industry > standard, and once there were several implementations of optional out there, > they started to pull one in. They just didn't manage to write it without using > C++17'isms. std::optional has no fundamental c++17isms in it, and can be written without any problem in C++11 code. I maintain optional in libstdc++, in case you wonder on what basis I'm making that statement. The standard library imports a whole host of things that aren't always industry standards, but it imports things only when there's a proposal to import something. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Montag, 4. Dezember 2017 15:00:53 CET Marc Mutz wrote: > > Ah, well, yes. Nothing truly originates in C++, true. But, IIRC, the > Haskell name is maybe. So why is it QOptional and not QMaybe? Because > the C++ interface is used as the basis, not something from Haskell. > I believe the name "optional" comes from Haskell and Java where it appeared first. The standard library only imports things that are already industry standard, and once there were several implementations of optional out there, they started to pull one in. They just didn't manage to write it without using C++17'isms. The other name that sometimes gets used instead of Optional is Nullable (from SQL and C#), but that is a little different. I don't think "maybe" ever gets used much for this kind of type. Anyway. I do believe we should try to be compatible with std. I just don't see the point in throwing our hands in the air and refusing to improve our base classes while waiting for something we might be able to use 9 years from now. Btw. One of the issues with std::expected and std::outcome is that many are pushing for them to become C++ versions of Haskell monads, which complicates things. Best regard 'Allan ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-12-03 22:57, Allan Sandfeld Jensen wrote: On Samstag, 2. Dezember 2017 17:48:19 CET Marc Mutz wrote: If that analyis were true, you'd need to explain why it is, then, that the Qt containers now have more or less the same API as std ones, when in Qt 1 they were very different. And why I keep needing to fight off QOptional. These are ideas that do not come from Qt. They come from C++/Boost. What are you smoking? Nothing, atm. I did a cigarette once, though, after some scotch. Didn't end all that well... These come from ML/Haskell who have had types like that for decades. Ah, well, yes. Nothing truly originates in C++, true. But, IIRC, the Haskell name is maybe. So why is it QOptional and not QMaybe? Because the C++ interface is used as the basis, not something from Haskell. Alex Stepanov also agrees that vector may not have been his wisest naming choice for a dynamic array container, but it's still QVector, and not QArray, after all (IIRC, it actually _was_ QGArray in Qt 1). So, seems Qt's using C++ as a reference. As it should (whenever Java was used, things went bad: QList, QListIterator, ...). For better or worse, Qt is a C++ framework, so it's important to not try to invent new names for all things C++. Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Samstag, 2. Dezember 2017 17:48:19 CET Marc Mutz wrote: > If that analyis were true, you'd need to explain why it is, then, that > the Qt containers now have more or less the same API as std ones, when > in Qt 1 they were very different. And why I keep needing to fight off > QOptional. These are ideas that do not come from Qt. They come from > C++/Boost. What are you smoking? These come from ML/Haskell who have had types like that for decades. 'Allan ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
>> . I would be fine having the same developer experience in C++ > > even if I had to change name spaces and includes, but doesn't seem usual > > practice in C++. > > uh... ? I have been polyfilling optional, string_view, any, and variant for > almost three years with boost, or std/experimental/. The API is 99% > compatible to what's in std. FWIW, WebKit project is also doing this for years (by importing experimental implementations into the source tree) > > --- > Jean-Michaël Celerierhttp://www.jcelerier.name > > On Sun, Dec 3, 2017 at 5:41 PM, Alejandro Exojo via Development >wrote: > >> On Saturday 02 December 2017 19:11:23 Boudewijn Rempt wrote: >> >>> > > And, c'mon, std::optional's API is just not going to be topped by >> >>> > > QOptional. What should they do? snake_case vs. camelCase? That's what >> >>> > > we need to invest several man-days of development work in, to rename >> >>> > > the functions and stick a Q in front of the class name? >> >>> > >> >>> > There's one thing that a QOptional could do that std::optional can't: >> >>> > be available for all Qt users >> >>> > in a time span of a couple of months. >> >> True. And that, in my very humble opinion, highlights a common problem that >> >> people face in projects in all languages: wanting to use a standard >> >> functionality that is not yet available in the platforms that you have to >> >> support. Many other languages are able to "polyfill"/shim >> not-yet-standardized >> >> classes or functions (even members) in a clean way, by adding a 3rd party >> >> library and done. I would be fine having the same developer experience in C++ >> >> even if I had to change name spaces and includes, but doesn't seem usual >> >> practice in C++. >> >>> And another thing: be properly documented in a way that people who >> >>> are not CS phd's can understand. std completely and utterly fails >> >>> in that. Parts of Qt's docs are bad enough, but there's nothing in >> >>> cppreference.com that would pass muster for my gsoc students. >> >> I wholeheartedly agree. I understand the argument of the lambda in find_if >> in a >> >> somewhat intuitive way, but the explanations that one finds there about it >> are >> >> hugely discouraging to me (full of standardese), even if it's been some years >> >> using C++. It's not rare to see pages documenting a class or function, that, >> >> instead of giving examples of its usage, show instead three possible >> >> implementations. When you are trying to understand how it's used, or why it's >> >> useful. :-( >> >> And a 3rd point, that not necessarily applies to QOptional if everything is >> >> templated and inline, but I think still the main blocker for using more >> >> standard API is the lack of ABI stability. Yes, that's misfeature for some, >> >> but it's the current rule, so ignoring it is not helping the conversation, >> >> IMHO. >> >> -- >> >> Viking Software, Qt and C++ developers for hire >> >> http://www.vikingsoftware.com >> >> ___ >> >> Development mailing list >> >> Development@qt-project.org >> >> http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
> . I would be fine having the same developer experience in C++ even if I had to change name spaces and includes, but doesn't seem usual practice in C++. uh... ? I have been polyfilling optional, string_view, any, and variant for almost three years with boost, or std/experimental/. The API is 99% compatible to what's in std. --- Jean-Michaël Celerier http://www.jcelerier.name On Sun, Dec 3, 2017 at 5:41 PM, Alejandro Exojo via Development < development@qt-project.org> wrote: > On Saturday 02 December 2017 19:11:23 Boudewijn Rempt wrote: > > > > And, c'mon, std::optional's API is just not going to be topped by > > > > QOptional. What should they do? snake_case vs. camelCase? That's what > > > > we need to invest several man-days of development work in, to rename > > > > the functions and stick a Q in front of the class name? > > > > > > There's one thing that a QOptional could do that std::optional can't: > > > be available for all Qt users > > > in a time span of a couple of months. > > True. And that, in my very humble opinion, highlights a common problem that > people face in projects in all languages: wanting to use a standard > functionality that is not yet available in the platforms that you have to > support. Many other languages are able to "polyfill"/shim > not-yet-standardized > classes or functions (even members) in a clean way, by adding a 3rd party > library and done. I would be fine having the same developer experience in > C++ > even if I had to change name spaces and includes, but doesn't seem usual > practice in C++. > > > And another thing: be properly documented in a way that people who > > are not CS phd's can understand. std completely and utterly fails > > in that. Parts of Qt's docs are bad enough, but there's nothing in > > cppreference.com that would pass muster for my gsoc students. > > I wholeheartedly agree. I understand the argument of the lambda in find_if > in a > somewhat intuitive way, but the explanations that one finds there about it > are > hugely discouraging to me (full of standardese), even if it's been some > years > using C++. It's not rare to see pages documenting a class or function, > that, > instead of giving examples of its usage, show instead three possible > implementations. When you are trying to understand how it's used, or why > it's > useful. :-( > > And a 3rd point, that not necessarily applies to QOptional if everything is > templated and inline, but I think still the main blocker for using more > standard API is the lack of ABI stability. Yes, that's misfeature for some, > but it's the current rule, so ignoring it is not helping the conversation, > IMHO. > > -- > Viking Software, Qt and C++ developers for hire > http://www.vikingsoftware.com > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development > ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Saturday 02 December 2017 19:11:23 Boudewijn Rempt wrote: > > > And, c'mon, std::optional's API is just not going to be topped by > > > QOptional. What should they do? snake_case vs. camelCase? That's what > > > we need to invest several man-days of development work in, to rename > > > the functions and stick a Q in front of the class name? > > > > There's one thing that a QOptional could do that std::optional can't: > > be available for all Qt users > > in a time span of a couple of months. True. And that, in my very humble opinion, highlights a common problem that people face in projects in all languages: wanting to use a standard functionality that is not yet available in the platforms that you have to support. Many other languages are able to "polyfill"/shim not-yet-standardized classes or functions (even members) in a clean way, by adding a 3rd party library and done. I would be fine having the same developer experience in C++ even if I had to change name spaces and includes, but doesn't seem usual practice in C++. > And another thing: be properly documented in a way that people who > are not CS phd's can understand. std completely and utterly fails > in that. Parts of Qt's docs are bad enough, but there's nothing in > cppreference.com that would pass muster for my gsoc students. I wholeheartedly agree. I understand the argument of the lambda in find_if in a somewhat intuitive way, but the explanations that one finds there about it are hugely discouraging to me (full of standardese), even if it's been some years using C++. It's not rare to see pages documenting a class or function, that, instead of giving examples of its usage, show instead three possible implementations. When you are trying to understand how it's used, or why it's useful. :-( And a 3rd point, that not necessarily applies to QOptional if everything is templated and inline, but I think still the main blocker for using more standard API is the lack of ABI stability. Yes, that's misfeature for some, but it's the current rule, so ignoring it is not helping the conversation, IMHO. -- Viking Software, Qt and C++ developers for hire http://www.vikingsoftware.com ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-12-02 18:54, Ville Voutilainen wrote: On 2 December 2017 at 18:48, Marc Mutzwrote: If that analyis were true, you'd need to explain why it is, then, that the Qt containers now have more or less the same API as std ones, when in Qt 1 they were very different. And why I keep needing to fight off QOptional. .. And, c'mon, std::optional's API is just not going to be topped by QOptional. What should they do? snake_case vs. camelCase? That's what we need to invest several man-days of development work in, to rename the functions and stick a Q in front of the class name? There's one thing that a QOptional could do that std::optional can't: be available for all Qt users in a time span of a couple of months. And I'm not against it. I, personally, did that for qAsConst/std::as_const. And we had qtypetraits.h, too. But if we copy std functionality, it must be and stay 100% behaviour-compatible with the corresponding std type. As a consequence, it was trivial to move away from qtypetraits.h, and it will be trivial to move from qAsConst to std::as_const. The problem comes in when you add functionality to the Qt copy that is not in the std equivalent. As such, I'm asking, like for bug-fixes, to merge the feature upstream first, then implement it in Qt when it becomes apparent that upstream will adopt the change. And as with qtypetraits.h, we should _copy_ a 3rd-party component instead of implementing it ourselves. Another excellent example of correctly working with upstream is QRegularExpression. The author first added UTF-16 support to libpcre, and _then_ added QRegularExpression on top, instead of, like it was done for QRegExp, implement the automaton himself. The QRegularExpression API is also closer to std::regex than QRegExp. The latter, despite originating in Qt, does not really have a more convenient API than std::regex. But if a QOptional is added with a nullable-Qt-types optimisation already built-in, or QStringView(Char*) is missing constexpr when std::string_view(char*) does not, then this is a functional fork that I consider unacceptable. So, to summarize my position: 1. It's ok for Qt to add copies of std functionality. It may even have a Qt-ish API (QClass::camelCase()). 2. But it must never, ever, add functionality that the std equivalent does not have. 3. Unless Qt is leap-frogging in front of the std with this (like Unicode support in QString), functionally. Performance does not count, as that should be fixed upstream. 4. Even so, Qt-as-a-project should actively participate in upstreams (incl., but not limited to, the C++ standard) to get added functionality upstreamed. An example of (4) would be for TQC to participate in the text_view discussion. Another is Olivier's co-operation with Herb and Andrew on exploring porting Qt's metaobject system to C++ metaclasses. Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Sat, 02 Dec 2017 17:48:19 +0100 Marc Mutzwrote: > > 1) the std implementation varies with compiler vendors, each one with a > > different set of bugs, unit tests and sometimes performance. While with > > Qt, the implementation is more uniform. This to say, I feel more secure > > using Qt implementations for an application that runs on multiple > > platforms. And cross-platform is the core business of Qt... > > You make it sound as if std implementations are much more buggy than Qt's. I > don't even know how to respond. I'm sure STL, Marshal Clow, Howard Hinnant, > and all the others std library implementers will be pleased with your > analysis. This is not what I said. I want to say that all libraries have bugs, without telling that Qt is better or worse. But for a cross-platform developer, it is better to deal with one implementation than many. When a bug only happens on one platform, and you ship a cross-platform application, this it not cool! Philippe ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
>>And, c'mon, std::optional's API is just not going to be topped by QOptional. I don't know the QOptional plans (or no-plan), but as today, on the Mac, the latest XCode 9.1 still does not provide std::optional. With Qt, at least, when something is available, it is available in all platforms, and Qt users can count on that. >>Where I come from, we see customer's code "out there", and they almost never >>use Qt in isolation. >> They have to interface with some 2rd-party library which, naturally, does >> _not_ use Qt types, but std ones, >> and developers on those projects need to interact with both. >> They also surprisingly often know about and use Boost. >> Not only do they need to learn two different APIs (append() vs. push_back()), >> they also face the impedance mismatch between Qt and every other C++ library >> on the planet. I also see that, except that boost dependency is often rejected. But I also hear praises about Qt documentation and ease of learning. I like your expression "impedance mismatch", but don't see this as a problem in practise. I mean, when a std:: container needs to be used for an interface with another library, then let's use is. No big deal. Philippe On Sat, 02 Dec 2017 17:48:19 +0100 Marc Mutzwrote: > On 2017-12-01 23:12, Philippe wrote: > >>> it's existential for Qt to get off its own container classes. > >>> I shall in the future extend that statement to anything that overlaps > >>> with std. > > > > Two points to keep in mind: > > > > 1) the std implementation varies with compiler vendors, each one with a > > different set of bugs, unit tests and sometimes performance. While with > > Qt, the implementation is more uniform. This to say, I feel more secure > > using Qt implementations for an application that runs on multiple > > platforms. And cross-platform is the core business of Qt... > > You make it sound as if std implementations are much more buggy than Qt's. I > don't even know how to respond. I'm sure STL, Marshal Clow, Howard Hinnant, > and all the others std library implementers will be pleased with your > analysis. > > Have you tried using QVector with a type that has no default constructor? > Using that nice API forces users to supply an unnatural operation on their > types (if they control the types in the first place). > > As I said multiple times before: my arguments would be pretty weak if Qt's > implementation quality matched or exceeded the quality of the corresponding > feature in the standard library (and that's why we have QStringView, > incomplete as it still is, because of QString), but except for QString, and > QFuture, which, however, lacks the QPromise counterpart, I don't see any > other cases. > > > 2) a majority of Qt users are not C++ wizards, and ease of use / > > intuitive api, is of primary importance... std does not always shine > > here. > > If that analyis were true, you'd need to explain why it is, then, that the Qt > containers now have more or less the same API as std ones, when in Qt 1 they > were very different. And why I keep needing to fight off QOptional. These are > ideas that do not come from Qt. They come from C++/Boost. Qt is "stealing" > them, wrapping them up in a camelCase interface, omitting the hard parts of > the implementation, adding some optimisation for Qt types, and then stand > here as Thiago does and say that the Qt type needs to stay because of that > optimisation. Even new-style Qt 5 signal/slot connections were available in > this form in Boost since at least 1.32, ie. something like 2004. In Qt 3 > times, people would have protected loudly over the need to write ugly code > like ::returnPressed instead of SIGNAL(returnPressed()), but lo and > behold, there's been no public outcry. Qt silently adopted the interface that > was inspired by it's own invention, but had since succeeded in keeping up w ith the rest of the world (Boost.Signals). That's a _good_ change. It helps people integrate their code with Qt. because integrate they must. > > Where I come from, we see customer's code "out there", and they almost never > use Qt in isolation. They have to interface with some 2rd-party library > which, naturally, does _not_ use Qt types, but std ones, and developers on > those projects need to interact with both. They also surprisingly often know > about and use Boost. Not only do they need to learn two different APIs > (append() vs. push_back()), they also face the impedance mismatch between Qt > and every other C++ library on the planet. > > Developers just can't cocoon inside the Qt world. They need to interact with > the real world, and Qt actively prevents that with its copies of upstream > APIs all over the place, and it's antiquated (read: pre-C++11) programming > model. > > Two things have happened since 2010: C++ is progressing fast again, as a > language, and, more importantly, the _tooling_ situation has dramatically > improved. In a
Re: [Development] QtCS 2017 QtCore sessions
On Sat, 2 Dec 2017, Ville Voutilainen wrote: > On 2 December 2017 at 18:48, Marc Mutzwrote: > > If that analyis were true, you'd need to explain why it is, then, that the > > Qt containers now have more or less the same API as std ones, when in Qt 1 > > they were very different. And why I keep needing to fight off QOptional. > .. > > And, c'mon, std::optional's API is just not going to be topped by QOptional. > > What should they do? snake_case vs. camelCase? That's what we need to invest > > several man-days of development work in, to rename the functions and stick a > > Q in front of the class name? > > > There's one thing that a QOptional could do that std::optional can't: > be available for all Qt users > in a time span of a couple of months. And another thing: be properly documented in a way that people who are not CS phd's can understand. std completely and utterly fails in that. Parts of Qt's docs are bad enough, but there's nothing in cppreference.com that would pass muster for my gsoc students. -- Boudewijn Rempt | http://www.krita.org, http://www.valdyas.org ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2 December 2017 at 18:48, Marc Mutzwrote: > If that analyis were true, you'd need to explain why it is, then, that the > Qt containers now have more or less the same API as std ones, when in Qt 1 > they were very different. And why I keep needing to fight off QOptional. .. > And, c'mon, std::optional's API is just not going to be topped by QOptional. > What should they do? snake_case vs. camelCase? That's what we need to invest > several man-days of development work in, to rename the functions and stick a > Q in front of the class name? There's one thing that a QOptional could do that std::optional can't: be available for all Qt users in a time span of a couple of months. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-12-01 23:12, Philippe wrote: it's existential for Qt to get off its own container classes. I shall in the future extend that statement to anything that overlaps with std. Two points to keep in mind: 1) the std implementation varies with compiler vendors, each one with a different set of bugs, unit tests and sometimes performance. While with Qt, the implementation is more uniform. This to say, I feel more secure using Qt implementations for an application that runs on multiple platforms. And cross-platform is the core business of Qt... You make it sound as if std implementations are much more buggy than Qt's. I don't even know how to respond. I'm sure STL, Marshal Clow, Howard Hinnant, and all the others std library implementers will be pleased with your analysis. Have you tried using QVector with a type that has no default constructor? Using that nice API forces users to supply an unnatural operation on their types (if they control the types in the first place). As I said multiple times before: my arguments would be pretty weak if Qt's implementation quality matched or exceeded the quality of the corresponding feature in the standard library (and that's why we have QStringView, incomplete as it still is, because of QString), but except for QString, and QFuture, which, however, lacks the QPromise counterpart, I don't see any other cases. 2) a majority of Qt users are not C++ wizards, and ease of use / intuitive api, is of primary importance... std does not always shine here. If that analyis were true, you'd need to explain why it is, then, that the Qt containers now have more or less the same API as std ones, when in Qt 1 they were very different. And why I keep needing to fight off QOptional. These are ideas that do not come from Qt. They come from C++/Boost. Qt is "stealing" them, wrapping them up in a camelCase interface, omitting the hard parts of the implementation, adding some optimisation for Qt types, and then stand here as Thiago does and say that the Qt type needs to stay because of that optimisation. Even new-style Qt 5 signal/slot connections were available in this form in Boost since at least 1.32, ie. something like 2004. In Qt 3 times, people would have protected loudly over the need to write ugly code like ::returnPressed instead of SIGNAL(returnPressed()), but lo and behold, there's been no public outcry. Qt silently adopted the interface that was inspired by it's own invention, but had since succeeded in keeping up with the rest of the world (Boost.Signals). That's a _good_ change. It helps people integrate their code with Qt. because integrate they must. Where I come from, we see customer's code "out there", and they almost never use Qt in isolation. They have to interface with some 2rd-party library which, naturally, does _not_ use Qt types, but std ones, and developers on those projects need to interact with both. They also surprisingly often know about and use Boost. Not only do they need to learn two different APIs (append() vs. push_back()), they also face the impedance mismatch between Qt and every other C++ library on the planet. Developers just can't cocoon inside the Qt world. They need to interact with the real world, and Qt actively prevents that with its copies of upstream APIs all over the place, and it's antiquated (read: pre-C++11) programming model. Two things have happened since 2010: C++ is progressing fast again, as a language, and, more importantly, the _tooling_ situation has dramatically improved. In a world where your static analysis tools actively warn you about common Qt idioms (mutexes, but also naked new all over the place, in violation of CoreGuidelines), Qt's insistence on providing it's own copies of std functionality force users to choose between Qt-ish APIs or static analysis coverage. A developer that chooses a nicer API if there's another cross-platform alternative which is functionally at least on par, but better integrated with his tools (IDE, compiler, clang-tidy, ...) should have a long meeting with his manager. But Qt is just maintaining it's own NIH/our-APIs-are-superior stance. As evidenced by this thread. But it's users will move on. Personally, I'm doing more Modern C++ trainings than Qt trainings these days. That has to do with me not knowing QML much, but _also_ with a surge of interest in C++. And, c'mon, std::optional's API is just not going to be topped by QOptional. What should they do? snake_case vs. camelCase? That's what we need to invest several man-days of development work in, to rename the functions and stick a Q in front of the class name? Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
>>it's existential for Qt to get off its own container classes. >>I shall in the future extend that statement to anything that overlaps >>with std. Two points to keep in mind: 1) the std implementation varies with compiler vendors, each one with a different set of bugs, unit tests and sometimes performance. While with Qt, the implementation is more uniform. This to say, I feel more secure using Qt implementations for an application that runs on multiple platforms. And cross-platform is the core business of Qt... 2) a majority of Qt users are not C++ wizards, and ease of use / intuitive api, is of primary importance... std does not always shine here. Philippe On Fri, 01 Dec 2017 20:57:33 +0100 Marc Mutzwrote: > On 2017-12-01 19:26, Thiago Macieira wrote: > > On Friday, 1 December 2017 01:31:18 PST Marc Mutz wrote: > >> > Once those operator<=> are there, what benefit is there in having the > >> > API > >> > public and documented? > >> > >> The spaceship operator solves the problem for qCompareStrings(). One > >> could say we already have all relational operators for all > >> combinations > >> of string-like objects to solve it for the user _now_, but > >> qCompareStrings(), like operator<=>() return the full information, > >> while > >> relational operators only return a subset. You know that, I know. I'm > >> just mentioning it for completeness sake. > > > > Ok, so your case is when you have two string-like objects and you want > > to get > > the ordering result. Since we don't yet have the spaceship operator, > > you have > > to call the compare() function. But you can't do that in clean, generic > > code > > because you don't know if the first argument is an actual QString or > > QStringView, or if it's just a char16_t literal. > > > > Is that it? > > > > Why can't they write > > > > QStringView(s1).compare(s2) ? > > I think you owe me a bit more thought on an answer to a mail of mine that > that :P > A quick look at the qCompareString() overload set will answer this question > (hint: the lhs is not always QStringView). > > >> Ah, but you said that the flaw was in the _standard_. But what you > >> show > >> are sub-optimal compiler implementations. There's nothing in the > >> standard that prevents a compiler to implement char_traits::length() > >> as > >> a compiler intrinsic that can have different backends for constexpr > >> and > >> runtime evaluation. > > > > The flaw is in the standard because it does not allow me to implement > > an > > optimised version using whichever tools I want to. > > The standard is not obliged to publicly give you all the plumbing to > re-implement the standard library. The lack of plumbing is _sometimes_ a flaw > in the standard, yes (std::invoke), but not always. You are supposed to use > the standard library functionality, not re-implement it. In this case, the > interface is char_traits::length, it exists on all supported platforms and > does what we'd like it to do, incl., from C++17 on, constexpr. > > >> So, would the following be acceptable: > >> > >> 1. QSV uses char_traits::length() to calculate the length > >> (that was my initial implementation, but it's constexpr only starting > >> with C++17). Then QSV(Char*) is only constexpr in C++17. I can live > >> with > >> that. > > > > No, because... > > > >> 2. You/Intel work on the compiler vendors to get > >> char_traits::length() implemented as an intrinsic, with SIMD > >> at runtime and compiler magic at compile-time? > > > > We should do that anyway, but depending on it means we'll have > > performance in > > 2021 or later (just look at how we have to build Linux binaries with > > GCC 4.8). > > Since char_traits::length would be called from inline code in QSV, its > performance does not depend on how Qt was compiled, but on what the user's > compiler is capable of. Also, presumably, the compiler was already optimizing > char_traits::length() back when it wasn't constexpr (in C++11+14) and now has > to implement something to not regress on runtime performance while still > meeting constexpr restrictions. If it doesn't, then it's not our problem. > It's SEP. And that is good. Pick your battles. > > > The flaw exists today. My choice for fixing it is to sacrifice the part > > we > > don't really need: the constexprness. > > Fixing it in Qt is limiting both Qt and the standard library. Don't do that. > > > The same is true, btw, of QMutex. Qt takes pride in how QMutex is faster than > std::mutex. I think it's a shame. It shows that you didn't go the next step > and get std::mutex fixed. Having QMutex not use std::mutex means that tsan > doesn't work correctly, for one. Here, too, the "easy" local "fix" is to the > detriment of both the standard library (slower-than-necessary mutex > operations) and Qt (failure to work with tsan). > > This habit of cocooning might have worked out ok when Qt was years ahead of > the C++ standard library. But since those
Re: [Development] QtCS 2017 QtCore sessions
On 1 December 2017 at 22:35, Thiago Macieirawrote: > In theory, it's possible to use GCC 6 against an old set of libstdc++ headers. > > I don't know if the GCC devs officially support this (Ville, can you chime > in?). There's no attempt by GCC maintainers to make a newer compiler work with the older libstdc++ versions. They probably work, considering that the old library probably doesn't use any intrinsics and such the newer compiler doesn't have (modulo things that have been removed for one reason or another), but bug reports for such combinations are likely going to be outright rejected as invalid. For example, if there's some code in an old libstdc++ that the newer compiler doesn't accept, there's going to be exactly zero effort to fix that. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-12-01 20:57, Marc Mutz wrote: V8 fork, anyone? Or was it V4? ETOOMANYJSENGINES ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Friday, 1 December 2017 11:57:33 PST Marc Mutz wrote: > > Why can't they write > > > > QStringView(s1).compare(s2) ? > > I think you owe me a bit more thought on an answer to a mail of mine > that that :P > A quick look at the qCompareString() overload set will answer this > question (hint: the lhs is not always QStringView). I understand it isn't. But can't QStringView be constructed from any StringLike? What overhead do you get with the solution above that you wouldn't by calling qCompareString directly? > > The flaw is in the standard because it does not allow me to implement > > an > > optimised version using whichever tools I want to. > > The standard is not obliged to publicly give you all the plumbing to > re-implement the standard library. Most of it, it has to. The standard library is written in C++. The only exceptions should be chapter 21 "Language support library". > The lack of plumbing is _sometimes_ a > flaw in the standard, yes (std::invoke), but not always. You are > supposed to use the standard library functionality, not re-implement it. > In this case, the interface is char_traits::length, it exists on all > supported platforms and does what we'd like it to do, incl., from C++17 > on, constexpr. Except that it's not efficient. In fact, it *used* to be efficient in libc++ for char (strlen) and wchar_t (wcslen), but ceased to be because of the C++17 requirement for constexpr. I'm not accepting a performance regression. > >> 2. You/Intel work on the compiler vendors to get > >> char_traits::length() implemented as an intrinsic, with SIMD > >> at runtime and compiler magic at compile-time? > > > > We should do that anyway, but depending on it means we'll have > > performance in > > 2021 or later (just look at how we have to build Linux binaries with > > GCC 4.8). > > Since char_traits::length would be called from inline code in QSV, its > performance does not depend on how Qt was compiled, but on what the > user's compiler is capable of. Also, presumably, the compiler was > already optimizing char_traits::length() back when it wasn't constexpr > (in C++11+14) and now has to implement something to not regress on > runtime performance while still meeting constexpr restrictions. If it > doesn't, then it's not our problem. It's SEP. And that is good. Pick > your battles. I have picked my battles. As I said above, it used to be efficient in libc++ (using wcslen) then was made not to be so. See libcxx commit 291741 "Implement P0426: Constexpr for std::char_traits". Fortunately, I now see the LLVM developers applied the same hacky solution for libc++ that GCC devs did for libstdc++ to get performance back again. Also note in both cases this applies only to char and wchar_t. char16_t is not fixed. > > The flaw exists today. My choice for fixing it is to sacrifice the part > > we > > don't really need: the constexprness. > > Fixing it in Qt is limiting both Qt and the standard library. Don't do > that. I wouldn't mind co-authoring a paper about this. But we cannot wait for C++20 for it to be accepted for performance to pick back up. > > The same is true, btw, of QMutex. Qt takes pride in how QMutex is faster > than std::mutex. I think it's a shame. It shows that you didn't go the > next step and get std::mutex fixed. Having QMutex not use std::mutex > means that tsan doesn't work correctly, for one. Here, too, the "easy" > local "fix" is to the detriment of both the standard library > (slower-than-necessary mutex operations) and Qt (failure to work with > tsan). There's nothing wrong with std::mutex's definition. It can be made as efficient as QMutex, more than what QMutex is today and closer to what I have made it for Qt 6. It's just QoI: the libc++ and libstdc++ implementation operate on top of a pthread_mutex_t. If they ditch that, like we did, they can get the performance. It's an ABI-breaking change, though, because of std::mutex::native_handle_type. > This habit of cocooning might have worked out ok when Qt was years ahead > of the C++ standard library. But since those times in the 2000s, C++ has > overtaken Qt in all aspects the committee decided to take on. Qt will > have to adapt to this new reality or degrade to insignificance. Ride the > wave or drown. The corollary of what you're saying is that we need to continue innovating. That's what I believe I'm doing. And, again, where I think the committee got it wrong, I will NOT follow suit. Ditto for implementations, see QRandomGenerator. > As I said elsewhere: innovate, don't replicate. See the bigger picture > here: Where are the patches that integrate Qt's event system and > signal/slots mechanism with Coroutines, to name just one? Instead you > celebrate the perceived failures of the standard and Qt's ability to > "fix" them by writing a SIMD strlen or take the null state of a Qt value > class to optimize QOptional size. > > This pattern repeats and repeats. V8 fork, anyone? When will Qt
Re: [Development] QtCS 2017 QtCore sessions
On Friday, 1 December 2017 10:59:48 PST Jean-Michaël Celerier wrote: > > (just look at how we have to build Linux binaries with GCC 4.8). > > Isn't it possible to use a newer GCC but to tell it to use GCC 4.8's ABI ? > eg to target GCC 4.8, by using -fabi-version=2 -D_GLIBCXX_USE_CXX11_ABI=0 Don't tempt fate. In theory, it's possible to use GCC 6 against an old set of libstdc++ headers. I don't know if the GCC devs officially support this (Ville, can you chime in?). I wouldn't try. Just use an older GCC. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-12-01 19:26, Thiago Macieira wrote: On Friday, 1 December 2017 01:31:18 PST Marc Mutz wrote: > Once those operator<=> are there, what benefit is there in having the > API > public and documented? The spaceship operator solves the problem for qCompareStrings(). One could say we already have all relational operators for all combinations of string-like objects to solve it for the user _now_, but qCompareStrings(), like operator<=>() return the full information, while relational operators only return a subset. You know that, I know. I'm just mentioning it for completeness sake. Ok, so your case is when you have two string-like objects and you want to get the ordering result. Since we don't yet have the spaceship operator, you have to call the compare() function. But you can't do that in clean, generic code because you don't know if the first argument is an actual QString or QStringView, or if it's just a char16_t literal. Is that it? Why can't they write QStringView(s1).compare(s2) ? I think you owe me a bit more thought on an answer to a mail of mine that that :P A quick look at the qCompareString() overload set will answer this question (hint: the lhs is not always QStringView). Ah, but you said that the flaw was in the _standard_. But what you show are sub-optimal compiler implementations. There's nothing in the standard that prevents a compiler to implement char_traits::length() as a compiler intrinsic that can have different backends for constexpr and runtime evaluation. The flaw is in the standard because it does not allow me to implement an optimised version using whichever tools I want to. The standard is not obliged to publicly give you all the plumbing to re-implement the standard library. The lack of plumbing is _sometimes_ a flaw in the standard, yes (std::invoke), but not always. You are supposed to use the standard library functionality, not re-implement it. In this case, the interface is char_traits::length, it exists on all supported platforms and does what we'd like it to do, incl., from C++17 on, constexpr. So, would the following be acceptable: 1. QSV uses char_traits::length() to calculate the length (that was my initial implementation, but it's constexpr only starting with C++17). Then QSV(Char*) is only constexpr in C++17. I can live with that. No, because... 2. You/Intel work on the compiler vendors to get char_traits::length() implemented as an intrinsic, with SIMD at runtime and compiler magic at compile-time? We should do that anyway, but depending on it means we'll have performance in 2021 or later (just look at how we have to build Linux binaries with GCC 4.8). Since char_traits::length would be called from inline code in QSV, its performance does not depend on how Qt was compiled, but on what the user's compiler is capable of. Also, presumably, the compiler was already optimizing char_traits::length() back when it wasn't constexpr (in C++11+14) and now has to implement something to not regress on runtime performance while still meeting constexpr restrictions. If it doesn't, then it's not our problem. It's SEP. And that is good. Pick your battles. The flaw exists today. My choice for fixing it is to sacrifice the part we don't really need: the constexprness. Fixing it in Qt is limiting both Qt and the standard library. Don't do that. The same is true, btw, of QMutex. Qt takes pride in how QMutex is faster than std::mutex. I think it's a shame. It shows that you didn't go the next step and get std::mutex fixed. Having QMutex not use std::mutex means that tsan doesn't work correctly, for one. Here, too, the "easy" local "fix" is to the detriment of both the standard library (slower-than-necessary mutex operations) and Qt (failure to work with tsan). This habit of cocooning might have worked out ok when Qt was years ahead of the C++ standard library. But since those times in the 2000s, C++ has overtaken Qt in all aspects the committee decided to take on. Qt will have to adapt to this new reality or degrade to insignificance. Ride the wave or drown. As I said elsewhere: innovate, don't replicate. See the bigger picture here: Where are the patches that integrate Qt's event system and signal/slots mechanism with Coroutines, to name just one? Instead you celebrate the perceived failures of the standard and Qt's ability to "fix" them by writing a SIMD strlen or take the null state of a Qt value class to optimize QOptional size. This pattern repeats and repeats. V8 fork, anyone? When will Qt _finally_ learn? :) I said in my talks about QStringView that it's existential for Qt to get off its own container classes. I shall in the future extend that statement to anything that overlaps with std. I explicitly do not exclude QString here, even though it's exempt for the time being. But people _do_ talk about a std::text_view, and it _will_ support utf8 strings and that, in
Re: [Development] QtCS 2017 QtCore sessions
> (just look at how we have to build Linux binaries with GCC 4.8). Isn't it possible to use a newer GCC but to tell it to use GCC 4.8's ABI ? eg to target GCC 4.8, by using -fabi-version=2 -D_GLIBCXX_USE_CXX11_ABI=0 Best, --- Jean-Michaël Celerier http://www.jcelerier.name On Fri, Dec 1, 2017 at 7:26 PM, Thiago Macieirawrote: > On Friday, 1 December 2017 01:31:18 PST Marc Mutz wrote: > > > Once those operator<=> are there, what benefit is there in having the > > > API > > > public and documented? > > > > The spaceship operator solves the problem for qCompareStrings(). One > > could say we already have all relational operators for all combinations > > of string-like objects to solve it for the user _now_, but > > qCompareStrings(), like operator<=>() return the full information, while > > relational operators only return a subset. You know that, I know. I'm > > just mentioning it for completeness sake. > > Ok, so your case is when you have two string-like objects and you want to > get > the ordering result. Since we don't yet have the spaceship operator, you > have > to call the compare() function. But you can't do that in clean, generic > code > because you don't know if the first argument is an actual QString or > QStringView, or if it's just a char16_t literal. > > Is that it? > > Why can't they write > > QStringView(s1).compare(s2) ? > > > And we have more than qCompareStrings(). How does operator<=> help with > > qFindString()/qIndexOf() (which is still missing)? Answer: it doesn't. > > There's no infix notation for find-in-string. And there probably never > > will be (fancy proposing operator=~, anyone?). > > In both cases, explain why we need to provide that. Why can't they write > > QStringView(s1).indexOf(s2) ? > > > Ah, but you said that the flaw was in the _standard_. But what you show > > are sub-optimal compiler implementations. There's nothing in the > > standard that prevents a compiler to implement char_traits::length() as > > a compiler intrinsic that can have different backends for constexpr and > > runtime evaluation. > > The flaw is in the standard because it does not allow me to implement an > optimised version using whichever tools I want to. > > > So, would the following be acceptable: > > > > 1. QSV uses char_traits::length() to calculate the length > > (that was my initial implementation, but it's constexpr only starting > > with C++17). Then QSV(Char*) is only constexpr in C++17. I can live with > > that. > > No, because... > > > 2. You/Intel work on the compiler vendors to get > > char_traits::length() implemented as an intrinsic, with SIMD > > at runtime and compiler magic at compile-time? > > We should do that anyway, but depending on it means we'll have performance > in > 2021 or later (just look at how we have to build Linux binaries with GCC > 4.8). > > The flaw exists today. My choice for fixing it is to sacrifice the part we > don't really need: the constexprness. > > > Then we fix the problem where it should be fixed, and just piggy-back on > > the more general solution. And it's easy to sell to QSV users why that > > ctor is not constexpr until C++17 (and we don't even need any #ifdefery > > in the implementation). > > > > What do you think? > > We should fix the standard and we should help fix the implementations. But > I'm > not accepting a performance drawback for 3 or more years until then. > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development > ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Friday, 1 December 2017 01:31:18 PST Marc Mutz wrote: > > Once those operator<=> are there, what benefit is there in having the > > API > > public and documented? > > The spaceship operator solves the problem for qCompareStrings(). One > could say we already have all relational operators for all combinations > of string-like objects to solve it for the user _now_, but > qCompareStrings(), like operator<=>() return the full information, while > relational operators only return a subset. You know that, I know. I'm > just mentioning it for completeness sake. Ok, so your case is when you have two string-like objects and you want to get the ordering result. Since we don't yet have the spaceship operator, you have to call the compare() function. But you can't do that in clean, generic code because you don't know if the first argument is an actual QString or QStringView, or if it's just a char16_t literal. Is that it? Why can't they write QStringView(s1).compare(s2) ? > And we have more than qCompareStrings(). How does operator<=> help with > qFindString()/qIndexOf() (which is still missing)? Answer: it doesn't. > There's no infix notation for find-in-string. And there probably never > will be (fancy proposing operator=~, anyone?). In both cases, explain why we need to provide that. Why can't they write QStringView(s1).indexOf(s2) ? > Ah, but you said that the flaw was in the _standard_. But what you show > are sub-optimal compiler implementations. There's nothing in the > standard that prevents a compiler to implement char_traits::length() as > a compiler intrinsic that can have different backends for constexpr and > runtime evaluation. The flaw is in the standard because it does not allow me to implement an optimised version using whichever tools I want to. > So, would the following be acceptable: > > 1. QSV uses char_traits::length() to calculate the length > (that was my initial implementation, but it's constexpr only starting > with C++17). Then QSV(Char*) is only constexpr in C++17. I can live with > that. No, because... > 2. You/Intel work on the compiler vendors to get > char_traits::length() implemented as an intrinsic, with SIMD > at runtime and compiler magic at compile-time? We should do that anyway, but depending on it means we'll have performance in 2021 or later (just look at how we have to build Linux binaries with GCC 4.8). The flaw exists today. My choice for fixing it is to sacrifice the part we don't really need: the constexprness. > Then we fix the problem where it should be fixed, and just piggy-back on > the more general solution. And it's easy to sell to QSV users why that > ctor is not constexpr until C++17 (and we don't even need any #ifdefery > in the implementation). > > What do you think? We should fix the standard and we should help fix the implementations. But I'm not accepting a performance drawback for 3 or more years until then. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-11-30 22:13, Thiago Macieira wrote: On Thursday, 30 November 2017 12:08:45 PST Marc Mutz wrote: Don't go off on a tangent here. I used concepts syntax to keep the example simple. I can post with std::enable_if, if you prefer :) Fair enough, I had not considered that. Anyway, the point is the asymmetry of member functions. u"Hello".compare(string) does not compile in C++ (it does in Java), so everyone that wants to write a template like the op== above will have to re-invent qCompareStrings(). The Qt API rules stipulate that the common use case should be made simple (we do, we have member functions whereever we can add them), but make the rest possible. And that's where qCompareStrings() come in. It makes the remaining 5% (random number) possible. Why does anyone besides us need to write the op== like above? We have access to QtPrivate::qCompareStrings, so we can write the comparisons to our string objects. Once those operator<=> are there, what benefit is there in having the API public and documented? The spaceship operator solves the problem for qCompareStrings(). One could say we already have all relational operators for all combinations of string-like objects to solve it for the user _now_, but qCompareStrings(), like operator<=>() return the full information, while relational operators only return a subset. You know that, I know. I'm just mentioning it for completeness sake. And we have more than qCompareStrings(). How does operator<=> help with qFindString()/qIndexOf() (which is still missing)? Answer: it doesn't. There's no infix notation for find-in-string. And there probably never will be (fancy proposing operator=~, anyone?). [...] We all think we're smarter than the committee, yes. Maybe we are, but swarm intelligence suggests otherwise. To be clear: there's nothing wrong with adding constexpr where we can. Constexpr string literals make a lot of sense. The flaw is in doing that in detriment to performance at runtime. EVERY SINGLE strlen function is SIMD-optimised, sometimes even multiple versions. There's even a dedicated instruction added to SSE4.2 to do that, plus the original 8086 way (rep scasb) which was slow for a long time and now is fast again. I don't have the benchmarks to prove it, but my gut feeling is that the SIMD code becomes worth it very quickly (despite the call overhead), sometime between 8 and 16 characters in the string. https://godbolt.org/g/gBMykD Ah, but you said that the flaw was in the _standard_. But what you show are sub-optimal compiler implementations. There's nothing in the standard that prevents a compiler to implement char_traits::length() as a compiler intrinsic that can have different backends for constexpr and runtime evaluation. So, would the following be acceptable: 1. QSV uses char_traits::length() to calculate the length (that was my initial implementation, but it's constexpr only starting with C++17). Then QSV(Char*) is only constexpr in C++17. I can live with that. 2. You/Intel work on the compiler vendors to get char_traits::length() implemented as an intrinsic, with SIMD at runtime and compiler magic at compile-time? Then we fix the problem where it should be fixed, and just piggy-back on the more general solution. And it's easy to sell to QSV users why that ctor is not constexpr until C++17 (and we don't even need any #ifdefery in the implementation). What do you think? Thanks, Marc That is, unless compiler vendors haven't yet done this already. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Thursday, 30 November 2017 12:08:45 PST Marc Mutz wrote: > Don't go off on a tangent here. I used concepts syntax to keep the > example simple. I can post with std::enable_if, if you prefer :) Fair enough, I had not considered that. > Anyway, the point is the asymmetry of member functions. > u"Hello".compare(string) does not compile in C++ (it does in Java), so > everyone that wants to write a template like the op== above will have to > re-invent qCompareStrings(). The Qt API rules stipulate that the common > use case should be made simple (we do, we have member functions > whereever we can add them), but make the rest possible. And that's where > qCompareStrings() come in. It makes the remaining 5% (random number) > possible. Why does anyone besides us need to write the op== like above? We have access to QtPrivate::qCompareStrings, so we can write the comparisons to our string objects. Once those operator<=> are there, what benefit is there in having the API public and documented? > >> IMNSHO, absent proof to the contrary, you are optimizing an edge case > >> here, an edge case that people can easily fix by using > >> > >> auto s = QStringView{s, qustrlen(s)}; > >> > >> manually when they expect large strings. The missing constexpr is not > >> so > >> easily obtained than the SIMD length calculation. > > > > This was a judgement call. The C++ standard needs to be fixed, so I am > > doing > > what I think is the correct direction: performance first. > > And I would interpret the Qt API design rules differently: like > qCompareStrings(), constexpr QSV ctors enable the remaining 5% of > use-cases. If the standard equivalent wasn't constexpr all-over, one > could maintain that what people don't know they will not miss. But > std::string_view _is_ all-constexpr, and therefore (some) people will > miss it. Again, flaw in the standard. I do not feel we need to agree with the standard when it's flawed. I'll happily add constexprness back when I'm allowed to have my cake and eat it too. > That leaves the question whether long raw strings passed to > QSV(Char*) without also passing the length are the common use-case or > whether the common use-case is that the user doesn't care. And I think > that it's the latter, because off the top of my head, I can think of no > situation where I actually would need the length calculation in QSV's > ctor. The situation is a bit different in std::string_view where this > ctor also receives all C string literals. We have a separate ctor for > that in QSV, so we don't depend so existentially on the (Char*) ctor to > be constexpr, but we also don't have a performance problem, since the > frequency of calls to that ctor is very, very low. And there's the > work-around to enable the 10% (random number) of users that see a > performance problem with that ctor to call qustrlen() manually. I'd say that calling qustrlen manually is even more surprising and no one would think of doing that. Not even after finding that there's a bit of performance they could gain. Everyone just expects the constructor to calculate the length by itself. > > API parallelism with the Standard Library is not required where the > > standard > > library makes mistakes. Requiring constexpr for calculating string > > lengths is > > one where I think it made a mistake. Therefore, I will not accept that > > as an > > argument. > > We all think we're smarter than the committee, yes. Maybe we are, but > swarm intelligence suggests otherwise. To be clear: there's nothing wrong with adding constexpr where we can. Constexpr string literals make a lot of sense. The flaw is in doing that in detriment to performance at runtime. EVERY SINGLE strlen function is SIMD-optimised, sometimes even multiple versions. There's even a dedicated instruction added to SSE4.2 to do that, plus the original 8086 way (rep scasb) which was slow for a long time and now is fast again. I don't have the benchmarks to prove it, but my gut feeling is that the SIMD code becomes worth it very quickly (despite the call overhead), sometime between 8 and 16 characters in the string. https://godbolt.org/g/gBMykD -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-11-30 20:09, Thiago Macieira wrote: On quinta-feira, 30 de novembro de 2017 10:53:33 PST Marc Mutz wrote: What's wrong with str.compare()? Do these two quotes somehow fit together? template bool operator==(const LHS , const RHS ) { return qCompareStrings(lhs, rhs) == 0; } template bool operator==(const LHS , const RHS ) { return lhs.compare(rhs) == 0; } if (u"Hello" == string) ~~~ I don't see how this problem can't be solved. We don't need templates with StringLike concepts. Not to mention we can't really rely on them in Qt for the next 10 years, so if you want to write that last line of code, we'll need a solution without concepts. Don't go off on a tangent here. I used concepts syntax to keep the example simple. I can post with std::enable_if, if you prefer :) Anyway, the point is the asymmetry of member functions. u"Hello".compare(string) does not compile in C++ (it does in Java), so everyone that wants to write a template like the op== above will have to re-invent qCompareStrings(). The Qt API rules stipulate that the common use case should be made simple (we do, we have member functions whereever we can add them), but make the rest possible. And that's where qCompareStrings() come in. It makes the remaining 5% (random number) possible. 2. So ok, performance matters. But a flexible interface matters too. You might not use compile-time string manipulation, but people do. They write compile-time JSON parsers. Anyway, assuming you are right (and I don't think you are, here), where are your numbers that show that the frequency of calls to the QStringView(Char*) ctor multiplied with the performance increase of out-of-line SIMD code multiplied by the average length of strings is so large as to warrant dropping support for compile-time string manipulations and std compatibility? Show them, and then we'll discuss it again. IMNSHO, absent proof to the contrary, you are optimizing an edge case here, an edge case that people can easily fix by using auto s = QStringView{s, qustrlen(s)}; manually when they expect large strings. The missing constexpr is not so easily obtained than the SIMD length calculation. This was a judgement call. The C++ standard needs to be fixed, so I am doing what I think is the correct direction: performance first. And I would interpret the Qt API design rules differently: like qCompareStrings(), constexpr QSV ctors enable the remaining 5% of use-cases. If the standard equivalent wasn't constexpr all-over, one could maintain that what people don't know they will not miss. But std::string_view _is_ all-constexpr, and therefore (some) people will miss it. That leaves the question whether long raw strings passed to QSV(Char*) without also passing the length are the common use-case or whether the common use-case is that the user doesn't care. And I think that it's the latter, because off the top of my head, I can think of no situation where I actually would need the length calculation in QSV's ctor. The situation is a bit different in std::string_view where this ctor also receives all C string literals. We have a separate ctor for that in QSV, so we don't depend so existentially on the (Char*) ctor to be constexpr, but we also don't have a performance problem, since the frequency of calls to that ctor is very, very low. And there's the work-around to enable the 10% (random number) of users that see a performance problem with that ctor to call qustrlen() manually. We should empower, not infantilise, the user. API parallelism with the Standard Library is not required where the standard library makes mistakes. Requiring constexpr for calculating string lengths is one where I think it made a mistake. Therefore, I will not accept that as an argument. We all think we're smarter than the committee, yes. Maybe we are, but swarm intelligence suggests otherwise. Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Thursday, 30 November 2017 11:09:01 PST Thiago Macieira wrote: > API parallelism with the Standard Library is not required where the standard > library makes mistakes. Requiring constexpr for calculating string lengths > is one where I think it made a mistake. Therefore, I will not accept that > as an argument. >From libstdc++ std::char_traits static _GLIBCXX17_CONSTEXPR size_t length(const char_type* __s) { #if __cplusplus > 201402 if (__constant_string_p(__s)) return __gnu_cxx::char_traits::length(__s); else #endif return wcslen(__s); } They were added in revision 249137 by Pedro Alves. The fact that they needed to add that __constant_string_p hack indicates there's a design flaw. I'm not saying the change author agrees there's a defect, I'm saying change points to a design flaw. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quinta-feira, 30 de novembro de 2017 10:53:33 PST Marc Mutz wrote: > What's wrong with str.compare()? > > Do these two quotes somehow fit together? > >template >bool operator==(const LHS , const RHS ) >{ return qCompareStrings(lhs, rhs) == 0; } > >template >bool operator==(const LHS , const RHS ) >{ return lhs.compare(rhs) == 0; } > >if (u"Hello" == string) ~~~ I don't see how this problem can't be solved. We don't need templates with StringLike concepts. Not to mention we can't really rely on them in Qt for the next 10 years, so if you want to write that last line of code, we'll need a solution without concepts. > 2. So ok, performance matters. But a flexible interface matters too. You > might not use compile-time string manipulation, but people do. They > write compile-time JSON parsers. Anyway, assuming you are right (and I > don't think you are, here), where are your numbers that show that the > frequency of calls to the QStringView(Char*) ctor multiplied with the > performance increase of out-of-line SIMD code multiplied by the average > length of strings is so large as to warrant dropping support for > compile-time string manipulations and std compatibility? Show them, and > then we'll discuss it again. > > IMNSHO, absent proof to the contrary, you are optimizing an edge case > here, an edge case that people can easily fix by using > > auto s = QStringView{s, qustrlen(s)}; > > manually when they expect large strings. The missing constexpr is not so > easily obtained than the SIMD length calculation. This was a judgement call. The C++ standard needs to be fixed, so I am doing what I think is the correct direction: performance first. API parallelism with the Standard Library is not required where the standard library makes mistakes. Requiring constexpr for calculating string lengths is one where I think it made a mistake. Therefore, I will not accept that as an argument. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-11-30 17:13, Thiago Macieira wrote: On quinta-feira, 30 de novembro de 2017 06:02:19 PST Marc Mutz wrote: On 2017-10-10 14:49, Thiago Macieira wrote: [...] > * We think members are cleaner and we don't want to add these You have members where members are possible. But you can't add members to char16_t[]! Why would we need to? [...] [1] e.g., at some point, we should make operator==(string-like, string-like) templated and just call qCompareStrings. There's no reason to hold this API from the user. What's wrong with str.compare()? Do these two quotes somehow fit together? template bool operator==(const LHS , const RHS ) { return qCompareStrings(lhs, rhs) == 0; } template bool operator==(const LHS , const RHS ) { return lhs.compare(rhs) == 0; } if (u"Hello" == string) ~~~ [2] incl., btw, the constexpr on QStringView(Char*), which is required for std::string_view compat: http://en.cppreference.com/w/cpp/string/basic_string_view/basic_string_view Pity. Performance is more important than constexpr. 1. There are so many more performance problems in Qt than this that it's almost funny :) 2. So ok, performance matters. But a flexible interface matters too. You might not use compile-time string manipulation, but people do. They write compile-time JSON parsers. Anyway, assuming you are right (and I don't think you are, here), where are your numbers that show that the frequency of calls to the QStringView(Char*) ctor multiplied with the performance increase of out-of-line SIMD code multiplied by the average length of strings is so large as to warrant dropping support for compile-time string manipulations and std compatibility? Show them, and then we'll discuss it again. IMNSHO, absent proof to the contrary, you are optimizing an edge case here, an edge case that people can easily fix by using auto s = QStringView{s, qustrlen(s)}; manually when they expect large strings. The missing constexpr is not so easily obtained than the SIMD length calculation. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quinta-feira, 30 de novembro de 2017 06:02:19 PST Marc Mutz wrote: > On 2017-10-10 14:49, Thiago Macieira wrote: > [...] > > > * We think members are cleaner and we don't want to add these > > You have members where members are possible. > But you can't add members to char16_t[]! Why would we need to? > > * However, we already have some of those! qStartsWith > > ** Global namespace *and* documented > > ** foo.startsWith(bar) vs qStartsWith(foo, bar) > > ** Same conclusion, probably mark \internal, namespace them > > *** But review the changes to see what our arguments were on making > > them > > public > > I have seen that you used my recent absence to sneak in a change to put > these functions into the QtPrivate namespace - in a public header! It's > good that you agree that there should be free functions for them, it's a > pity that you think you need to hide them. I did not know you were absent when this was posted. Sorry, we cannot be held to blame for your employer deciding to suspend participation for a while. Qt development did not stop. You'll note I had agreed with you when those functions came in. It was during the QtCore session at QtCS that when I brought them up, people cringed and asked whether it was the Qt-way. The conclusion was it wasn't, so I posted here *and* in the API review that we were going to change. > No-one forces anyone to use them, but they are there for when you need > them: for use in generic code, to have one syntax that works for every > pair of arguments[1]. People are still free to use vec.begin(), and > personally, I'll choose that every time over std::begin(vec), but > std::begin() needs to be there, too. Same thing for qCompareStrings(). We just didn't want to make them officially part of the API. > I will not restart work on QStringView before these are put back. So, > please, restore them to the state they had[2], then I'll get approval > for finishing the work on QStringView. If it's too late for 5.10, add > them back as inline functions, calling the useless QtPrivate ones, > please. It's too late for 5.10, but we can add them as inline functions for 5.11, if there's strong reason. I don't believe there is. The reason is still the same: we don't want them in the API. > [1] e.g., at some point, we should make operator==(string-like, > string-like) templated and just call qCompareStrings. There's no reason > to hold this API from the user. What's wrong with str.compare()? > [2] incl., btw, the constexpr on QStringView(Char*), which is required > for std::string_view compat: > http://en.cppreference.com/w/cpp/string/basic_string_view/basic_string_view Pity. Performance is more important than constexpr. This stays until C++ allows us to overload constexpr and non-constexpr. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-10-10 14:49, Thiago Macieira wrote: [...] * We think members are cleaner and we don't want to add these You have members where members are possible. But you can't add members to char16_t[]! * However, we already have some of those! qStartsWith ** Global namespace *and* documented ** foo.startsWith(bar) vs qStartsWith(foo, bar) ** Same conclusion, probably mark \internal, namespace them *** But review the changes to see what our arguments were on making them public I have seen that you used my recent absence to sneak in a change to put these functions into the QtPrivate namespace - in a public header! It's good that you agree that there should be free functions for them, it's a pity that you think you need to hide them. No-one forces anyone to use them, but they are there for when you need them: for use in generic code, to have one syntax that works for every pair of arguments[1]. People are still free to use vec.begin(), and personally, I'll choose that every time over std::begin(vec), but std::begin() needs to be there, too. Same thing for qCompareStrings(). I will not restart work on QStringView before these are put back. So, please, restore them to the state they had[2], then I'll get approval for finishing the work on QStringView. If it's too late for 5.10, add them back as inline functions, calling the useless QtPrivate ones, please. Thanks, Marc [1] e.g., at some point, we should make operator==(string-like, string-like) templated and just call qCompareStrings. There's no reason to hold this API from the user. [2] incl., btw, the constexpr on QStringView(Char*), which is required for std::string_view compat: http://en.cppreference.com/w/cpp/string/basic_string_view/basic_string_view ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
Op 01/11/2017 om 22:27 schreef Thiago Macieira: > On quarta-feira, 1 de novembro de 2017 13:15:11 PDT André Somers wrote: >> That doesn't make sense. Of course it allows for that. >> >> You'd give indexOf a flag like Qt::searchTowardsBeginning (default being >> Qt::searchTowardsEnd) to determine the direction to search in. Or do you >> mean that you want the result also to be counted from the end? > You're confusing lastIndexOf() which searchs backwards from the end with > indexOf() searching forwards from a position near the end. Yes, those two are orthogonal. Fine. That doesn't disqualify the solution IMO. In fact, I already separated the two in the suggested mock-API. > >> If all >> API's take the index counted from the begining there would not be much >> use for that. You either calculate it yourself by substracting the >> result from length(), or you add another flag and do something like >> std::optional indexOf(needle, startIndex, >> Qt::searchTowardsBeginning | Qt::asCountedFromEnd) . > Yeah, we won't do that. The QString, QByteArray and QVector can't be bigger > than the maximum size representable in qssize_t anyway. So we don't *need* > the > extra bit. Fine, but the argument was not about that. The comment I made was on if using negative indexes is good API to begin with. I think it is not. > > Since we don't need the extra bit, we will stick to signed because of its > benefits: > 1) overflow can be caught with sanitisers > 2) doesn't cause sign conversion warnings when converted to other signed >values > 3) the instruction from the committee is to use signed unless you explicitly >need modulo-2 overflow > 4) the standard library, if ever rewritten, will use signed counters > All that is really orthogonal to if you use negative indices as part of your API, which was what I was responding to in the first place. You used _that_ as an argument before, and I suggested that that is not such great API IMHO and nowadays I'd do that differently. However, the world we live in is one where Qt has had the current API for ages and changing that would break too much. André ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quarta-feira, 1 de novembro de 2017 13:15:11 PDT André Somers wrote: > That doesn't make sense. Of course it allows for that. > > You'd give indexOf a flag like Qt::searchTowardsBeginning (default being > Qt::searchTowardsEnd) to determine the direction to search in. Or do you > mean that you want the result also to be counted from the end? You're confusing lastIndexOf() which searchs backwards from the end with indexOf() searching forwards from a position near the end. > If all > API's take the index counted from the begining there would not be much > use for that. You either calculate it yourself by substracting the > result from length(), or you add another flag and do something like > std::optional indexOf(needle, startIndex, > Qt::searchTowardsBeginning | Qt::asCountedFromEnd) . Yeah, we won't do that. The QString, QByteArray and QVector can't be bigger than the maximum size representable in qssize_t anyway. So we don't *need* the extra bit. Since we don't need the extra bit, we will stick to signed because of its benefits: 1) overflow can be caught with sanitisers 2) doesn't cause sign conversion warnings when converted to other signed values 3) the instruction from the committee is to use signed unless you explicitly need modulo-2 overflow 4) the standard library, if ever rewritten, will use signed counters -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quarta-feira, 1 de novembro de 2017 12:03:27 PDT André Somers wrote: > Using signed for size types is crucial because the API expects to be able to > > count backwards from the end and needs to report failure in other > > situations. So unsigned is simply ruled out. > > I think we're stuck with that API indeed, but _if_ we had the freedom to > re-design it, it would not be my choice to do it this way. I'd sooner > choose for an explicit flag for the first case, and something like > std::optional as a return value to handle the error-reporting case. I'd > find that more explicit that using negative indices. However, I guess we > cannot possibly break API that badly in Qt 6, so doing something like > that is out of the question. That doesn't allow implementing indexOf() that searches from a position from the end. It's not just failure modes. So, no, even with a redesign we'd stick with signed. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
01.11.2017, 18:50, "Philippe": >> Using unsigned for size types is crucial in preventing signed overflow in >> pathological cases. > > During this interactive conference of "C++ gurus" (Herb Sutter, Bjarne > Stroustrup, Andrei Alexandrescu, Stephan T. Lavavej, Chandler Carruth, > Sean Parent, Scott Meyers, Michael Wong), it is clearly stated that it's > generally a mistake to use unsigned... > Check these extracts! > https://www.youtube.com/watch?v=Puio5dly9N8#t=12m12s > https://www.youtube.com/watch?v=Puio5dly9N8#t=42m40s > https://www.youtube.com/watch?v=Puio5dly9N8#t=1h2m50s I've listened and I think I buy this. Their main argument is about mixing unsigned and signed, and Qt is a framework for a wide audience, and many people seem to pass negative numbers to APIs accepting unsigned without second thought (it's just a compiler warning, who looks at them after all), so using unsigned may increase number of bugs on user side. > > Philippe > > On Wed, 01 Nov 2017 18:25:01 +0300 > Konstantin Tokarev wrote: > >> 01.11.2017, 18:21, "Thiago Macieira" : >> > On quarta-feira, 1 de novembro de 2017 05:23:04 PDT ?? wrote: >> >> Sorry for digging the thread, but how is >> >> * use qssize_t >> >> and >> >> ** Wrapping std::{unordered_}map may be acceptable >> >> combines? >> >> std::*map uses size_t in it's API (size, max_size, count, reserve, >> >> begin(size_type), end(size_type)) >> > >> > Our wrapper API can still use qssize_t. >> > >> > "Won't that limit the actual maximum size?" >> > >> > No, not really, since it's already limited to half the full VM space. No >> > object can be larger than that. Using unsigned is unnecessary. >> >> Using unsigned for size types is crucial in preventing signed overflow in >> pathological cases. >> >> > >> >> And offtop - what about allocators? They would be accesibble for >> wrappers, >> >> but not accesible for QVector/QString? >> > >> > They wouldn't be accessible for wrappers either. >> > >> > -- >> > Thiago Macieira - thiago.macieira (AT) intel.com >> > Software Architect - Intel Open Source Technology Center >> > >> > ___ >> > Development mailing list >> > Development@qt-project.org >> > http://lists.qt-project.org/mailman/listinfo/development >> >> -- >> Regards, >> Konstantin >> ___ >> Development mailing list >> Development@qt-project.org >> http://lists.qt-project.org/mailman/listinfo/development > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
Op 01/11/2017 om 16:46 schreef Thiago Macieira: > On quarta-feira, 1 de novembro de 2017 08:25:01 PDT Konstantin Tokarev wrote: >>> No, not really, since it's already limited to half the full VM space. No >>> object can be larger than that. Using unsigned is unnecessary. >> Using unsigned for size types is crucial in preventing signed overflow in >> pathological cases. > Using signed for size types is crucial because the API expects to be able to > count backwards from the end and needs to report failure in other situations. > So unsigned is simply ruled out. I think we're stuck with that API indeed, but _if_ we had the freedom to re-design it, it would not be my choice to do it this way. I'd sooner choose for an explicit flag for the first case, and something like std::optional as a return value to handle the error-reporting case. I'd find that more explicit that using negative indices. However, I guess we cannot possibly break API that badly in Qt 6, so doing something like that is out of the question. André ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quarta-feira, 1 de novembro de 2017 08:58:35 PDT Konstantin Tokarev wrote: > > There are also no pathological cases since there is no overflow. > > There is overflow, try e.g. QByteArray::fromBase64() with array of size > larger than INT_MAX / 3 Everywhere where they may be overflow, you need to be careful and detect said overflow. Using signed or unsigned makes no difference: overflowing is bad. > If size was unsigned such bugs wouldn't lead to crashes or potential > security issues Or they would. In QUtf8::convertFromUnicode: QByteArray result(len * 3, Qt::Uninitialized); If size() were unsigned and larger than UINT_MAX / 3, then that multiplication would overflow. The result could potentially be a very small number. uchar *dst = reinterpret_cast(const_cast(result.constData())); const ushort *src = reinterpret_cast(uc); const ushort *const end = src + len; while (src != end) { ... } That loop never rechecks the size of the allocation. It simply assumes that the destination buffer is large enough to encode the worst case of the UTF-8 This means the use of unsigned would not prevent issues. The loop would still corrupt memory and could crash. What's more, the unsigned overflow is not wrong. So you can't flag down the issue by using a sanitiser. If we keep it as signed, then that multiplication can be flagged and fixed. qnumeric_p.h has add_overflow and mul_overflow for unsigned types. For a proper signed check, you really need help from the compiler. But we can add them on top of the unsigned ones for the ones that don't help (MSVC), by using the implementation-defined behaviour of how an unsigned number gets converted to signed. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
01.11.2017, 18:46, "Thiago Macieira": > On quarta-feira, 1 de novembro de 2017 08:25:01 PDT Konstantin Tokarev wrote: >> > No, not really, since it's already limited to half the full VM space. No >> > object can be larger than that. Using unsigned is unnecessary. >> >> Using unsigned for size types is crucial in preventing signed overflow in >> pathological cases. > > Using signed for size types is crucial because the API expects to be able to > count backwards from the end and needs to report failure in other situations. > So unsigned is simply ruled out. Indeed, it's crucial to keep backward compatibility in API (Yet counting backwards is nothing more than a sugar, and STL containers cope fine with size_t) > > There are also no pathological cases since there is no overflow. There is overflow, try e.g. QByteArray::fromBase64() with array of size larger than INT_MAX / 3 If size was unsigned such bugs wouldn't lead to crashes or potential security issues > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 1 November 2017 at 17:46, Thiago Macieirawrote: > On quarta-feira, 1 de novembro de 2017 08:25:01 PDT Konstantin Tokarev wrote: >> > No, not really, since it's already limited to half the full VM space. No >> > object can be larger than that. Using unsigned is unnecessary. >> >> Using unsigned for size types is crucial in preventing signed overflow in >> pathological cases. > > Using signed for size types is crucial because the API expects to be able to > count backwards from the end and needs to report failure in other situations. > So unsigned is simply ruled out. > > There are also no pathological cases since there is no overflow. If your signed size type would ever overflow, a sanitizer can catch that. It's *much* harder for a sanitizer to diagnose incorrect wrap-around of an unsigned size type if that sanitizer wishes to avoid false positives. Having said that, it's non-trivial for a sanitizer to diagnose signed overflow, since that happens to work correctly and in the way the programmer expected on many platforms. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
> Using unsigned for size types is crucial in preventing signed overflow in > pathological cases. During this interactive conference of "C++ gurus" (Herb Sutter, Bjarne Stroustrup, Andrei Alexandrescu, Stephan T. Lavavej, Chandler Carruth, Sean Parent, Scott Meyers, Michael Wong), it is clearly stated that it's generally a mistake to use unsigned... Check these extracts! https://www.youtube.com/watch?v=Puio5dly9N8#t=12m12s https://www.youtube.com/watch?v=Puio5dly9N8#t=42m40s https://www.youtube.com/watch?v=Puio5dly9N8#t=1h2m50s Philippe On Wed, 01 Nov 2017 18:25:01 +0300 Konstantin Tokarevwrote: > > > 01.11.2017, 18:21, "Thiago Macieira" : > > On quarta-feira, 1 de novembro de 2017 05:23:04 PDT ?? wrote: > >> Sorry for digging the thread, but how is > >> * use qssize_t > >> and > >> ** Wrapping std::{unordered_}map may be acceptable > >> combines? > >> std::*map uses size_t in it's API (size, max_size, count, reserve, > >> begin(size_type), end(size_type)) > > > > Our wrapper API can still use qssize_t. > > > > "Won't that limit the actual maximum size?" > > > > No, not really, since it's already limited to half the full VM space. No > > object can be larger than that. Using unsigned is unnecessary. > > Using unsigned for size types is crucial in preventing signed overflow in > pathological cases. > > > > >> And offtop - what about allocators? They would be accesibble for wrappers, > >> but not accesible for QVector/QString? > > > > They wouldn't be accessible for wrappers either. > > > > -- > > Thiago Macieira - thiago.macieira (AT) intel.com > > Software Architect - Intel Open Source Technology Center > > > > ___ > > Development mailing list > > Development@qt-project.org > > http://lists.qt-project.org/mailman/listinfo/development > > -- > Regards, > Konstantin > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quarta-feira, 1 de novembro de 2017 08:25:01 PDT Konstantin Tokarev wrote: > > No, not really, since it's already limited to half the full VM space. No > > object can be larger than that. Using unsigned is unnecessary. > > Using unsigned for size types is crucial in preventing signed overflow in > pathological cases. Using signed for size types is crucial because the API expects to be able to count backwards from the end and needs to report failure in other situations. So unsigned is simply ruled out. There are also no pathological cases since there is no overflow. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quarta-feira, 1 de novembro de 2017 08:21:10 PDT Thiago Macieira wrote: > "Won't that limit the actual maximum size?" > > No, not really, since it's already limited to half the full VM space. No > object can be larger than that. Using unsigned is unnecessary. Huh... on second thought, this limit applies to std::vector, but not to other types, since they don't have a single memory block. That said, if you are using more than 2 GB in a container on a 32-bit system, you deserve the OOM conditions. Please upgrade to a 64-bit processor. They're only 10 years old now. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
01.11.2017, 18:21, "Thiago Macieira": > On quarta-feira, 1 de novembro de 2017 05:23:04 PDT Иван Комиссаров wrote: >> Sorry for digging the thread, but how is >> * use qssize_t >> and >> ** Wrapping std::{unordered_}map may be acceptable >> combines? >> std::*map uses size_t in it's API (size, max_size, count, reserve, >> begin(size_type), end(size_type)) > > Our wrapper API can still use qssize_t. > > "Won't that limit the actual maximum size?" > > No, not really, since it's already limited to half the full VM space. No > object can be larger than that. Using unsigned is unnecessary. Using unsigned for size types is crucial in preventing signed overflow in pathological cases. > >> And offtop - what about allocators? They would be accesibble for wrappers, >> but not accesible for QVector/QString? > > They wouldn't be accessible for wrappers either. > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On quarta-feira, 1 de novembro de 2017 05:23:04 PDT Иван Комиссаров wrote: > Sorry for digging the thread, but how is > * use qssize_t > and > ** Wrapping std::{unordered_}map may be acceptable > combines? > std::*map uses size_t in it's API (size, max_size, count, reserve, > begin(size_type), end(size_type)) Our wrapper API can still use qssize_t. "Won't that limit the actual maximum size?" No, not really, since it's already limited to half the full VM space. No object can be larger than that. Using unsigned is unnecessary. > And offtop - what about allocators? They would be accesibble for wrappers, > but not accesible for QVector/QString? They wouldn't be accessible for wrappers either. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
> Using virtual functions for allocation/deallocation doesn't seem like a > bright idea If you speak about performances, then you are wrong. The impact is neglictable compared to the rest of the allocations. This has been proved by the guys that pushed that C++17 feature, with extensive benchmarks. You can find a very complete study here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0089r1.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0213r0.pdf And if you like some videos on the topic, here the latest one from John Lakos: https://www.youtube.com/watch?v=nZNd5FjSquk https://www.youtube.com/watch?v=CFzuFNSpycI=8s Personnaly (and with a long experience with custom memory allocation), I am convinced about this new C+++17 approach. Philippe On Wed, 01 Nov 2017 15:32:23 +0300 Konstantin Tokarevwrote: > > > 01.11.2017, 15:30, "Philippe" : > > And offtop - what about allocators? They would be accesibble for wrappers, > > but not accesible for QVector/QString? > > > > Something sure, a Qt6 feature such as std::pmr::memory_resource (cf. > > https://www.youtube.com/watch?v=v3dz-AKOVL8) would be more than welcome for > > Qt containers and strings. > > Using virtual functions for allocation/deallocation doesn't seem like a > bright idea > > > > > Philippe > > > > On Wed, 1 Nov 2017 15:23:04 +0300 > > ?? wrote: > > > >> Sorry for digging the thread, but how is > >> * use qssize_t > >> and > >> ** Wrapping std::{unordered_}map may be acceptable > >> combines? > >> std::*map uses size_t in it's API (size, max_size, count, reserve, > >> begin(size_type), end(size_type)) > >> > >> And offtop - what about allocators? They would be accesibble for wrappers, > >> but not accesible for QVector/QString? > > > > , > > > > ___ > > Development mailing list > > Development@qt-project.org > > http://lists.qt-project.org/mailman/listinfo/development > > > -- > Regards, > Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
01.11.2017, 15:30, "Philippe": > And offtop - what about allocators? They would be accesibble for wrappers, > but not accesible for QVector/QString? > > Something sure, a Qt6 feature such as std::pmr::memory_resource (cf. > https://www.youtube.com/watch?v=v3dz-AKOVL8) would be more than welcome for > Qt containers and strings. Using virtual functions for allocation/deallocation doesn't seem like a bright idea > > Philippe > > On Wed, 1 Nov 2017 15:23:04 +0300 > ?? wrote: > >> Sorry for digging the thread, but how is >> * use qssize_t >> and >> ** Wrapping std::{unordered_}map may be acceptable >> combines? >> std::*map uses size_t in it's API (size, max_size, count, reserve, >> begin(size_type), end(size_type)) >> >> And offtop - what about allocators? They would be accesibble for wrappers, >> but not accesible for QVector/QString? > > , > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
And offtop - what about allocators? They would be accesibble for wrappers, but not accesible for QVector/QString? Something sure, a Qt6 feature such as std::pmr::memory_resource (cf. https://www.youtube.com/watch?v=v3dz-AKOVL8) would be more than welcome for Qt containers and strings. Philippe On Wed, 1 Nov 2017 15:23:04 +0300 ??wrote: Sorry for digging the thread, but how is > * use qssize_t > and > ** Wrapping std::{unordered_}map may be acceptable > combines? > > std::*map uses size_t in it's API (size, max_size, count, reserve, > begin(size_type), end(size_type)) > > > And offtop - what about allocators? They would be accesibble for wrappers, > but not accesible for QVector/QString? > > ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
Sorry for digging the thread, but how is * use qssize_t and ** Wrapping std::{unordered_}map may be acceptable combines? std::*map uses size_t in it's API (size, max_size, count, reserve, begin(size_type), end(size_type)) And offtop - what about allocators? They would be accesibble for wrappers, but not accesible for QVector/QString? ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
Some other comments here and there, Il 10/10/2017 14:49, Thiago Macieira ha scritto: [we combined the main and containers session; we did not have time for QIODevice] == Intro == Suggested topics: * QIODevice for Qt 6 * adding std::hash for Qt types As in: we're OK that this should be done. * expanding the hash seed to 64- or 128-bit But how, without breaking all the existing code? (Also, is it worth it?) == Use of standard C++ API == We will not add compilers that are worse than what we have today. * If all the compilers we have support things like std::mersenne_twister, then all will * We can add hard-fail configure test * Should we start migrating from QSharedPointer to std::shared_ptr? ** Deprecate ** Deprecate QScopedPointer Just noticed that we _do_ have QSharedPointer in our API, e.g.: https://doc.qt.io/qt-5/qquickitem.html#grabToImage (Yes, it's a totally and utterly broken signature, but that's it). Anyhow, in favour of deprecating QSharedPointer/QWeakPointer/QScopedPointer, as well as the atomic classes, and any other piece of functionality which has a _perfect_ replacement coming from the Standard Library. * What about API from C++17/20 that we'd like to use? ** Try to backport the API into a QtPrivate namespace (if it's been standardised) unless we want to add significant functionality a la QStringView ** If it's not standardised yet, use Qt-style naming Is it just as a general policy or was some specific request raised? * API naming ** std:: API naming is subtly different from Qt API (hopefully nothing that is confusing or misleading) ** We could try to create wrappers (container.empty() → container.isEmpty()) Wrappers for the STL classes, that is? == Modifiers vs getters for QString/QStringView/QByteArray == We don't want people to write: str = std::move(str).simplified() We want instead: str.simplify() So we want to add the full set of modifiers. In the sense that we want BOTH the modifier (imperative present) and the non-modifier copy (indicative simple past), right? Do we want to add freestanding functions that may operate on std::string and other string types? * Like qSimplify() * Polluting namespace Shove them in a namespace >:-) * They'd all need to be inline and some could be big Why they need to be inline? * freestanding brings in ADL and could introduce unexpected isues * We think members are cleaner and we don't want to add these * However, we already have some of those! qStartsWith ** Global namespace *and* documented The point of having those, however, is to make them work with _any_ string-viewable type, including those we can't add functions to (e.g. std::u16string). So, are we saying we don't care? ** foo.startsWith(bar) vs qStartsWith(foo, bar) ** Same conclusion, probably mark \internal, namespace them *** But review the changes to see what our arguments were on making them public Two birds with one stone: * the argument above (we've now got functions acting over types we don't / can't control) * and the fact that this way we can avoid adding methods everywhere, so we don't need to add the string function to all of our string classes. (This last argument is kind of weak, though, but I see the maintenance and testing burden.) == QStringView == * NEVER return QStringView (but QRegularExpression wants to) ** Consequence of "never return a reference" (but containers do) The C++ community is freaking out on string_view and it's right now in the "love it or hate it" mood. I don't get any of the hate -- personally I think it's just because we finally have a reference type that we _want_ to use everywhere, and so we now get the problems of reference types. So I'm not buying the "NEVER" return exactly -- you can, but you need to document what's the lifetime expectation of your QStringView (in other words, what's it tied to). ** Lifetime issues auto s = lineedit.text().left(n); s valid? A good chunk of these lifetime issues will likely be detectable via linters. No, not volunteering about adding the checks to clazy (but I hope that such checks will be added to clang-tidy and) == Containers == You cannot have all three: # Implicit sharing # Performance # Data-compatibility with std:: containers At this point in time, with the resources we have developing the containers (pretty much only Thiago at this point?), I'd rather go with 1+3. We will never be able to get rid of 1. So instead let's push away the implementation burden, get all the features implemented "for free", make the dealing with all the corner cases SEP (e.g. the infamous clear/resize/reserve behaviours, QMap insertion order, ...), and live with the small performance hit. QList: * [https://codereview.qt-project.org/194984 QUIP 9] Conclusions: * If we have QStringView, QArrayView, QByteArrayView, we don't need fromRawData() * We use qssize_t everywhere Not entirely buying this... Has anyone attempted to do the
Re: [Development] QtCS 2017 QtCore sessions
On Tuesday, 10 October 2017 05:49:48 PDT Thiago Macieira wrote: > Move to the containers session: > * use qssize_t By the way, re: https://bugreports.qt.io/browse/QTBUG-47629 We should use 64-bit in QJsonPrivate too. Specifically, because of the way that the internal binary JSON format stores values, we steal 5 bits from all possible lengths, causing the maximum JSON data to be limited to 128 MB. Apparently, it's not that difficult to hit that limit today. Given that we have QJsonDocument::fromRawData / fromBinaryData as public API, we need to keep compatibility with version 1 input for at least a couple more years, so if we do this change, we either need to keep both codepaths available or we need to reindex version 1 data. Any volunteers to look into this? -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On wtorek, 17 października 2017 17:28:54 CEST Marc Mutz wrote: > > (...) > > Discussion not finished > > I certainly hope so, because the above does not make any sense. See my > talk at QtWS. Returning QStringView is not different from c.begin() or > str.data(). You need to document the lifetime of the data, that's it. > (...) As a person reading docs only if something is not working as expected, I'm pondering, if there is a way to document the lifetime without documentation. It seems that QStringView shares problems of raw pointers and raw pointers issue was mostly solved by different smart pointers. So why not returning one of these: QViewValidAsLongAsObjectFoo QViewValidUntilTheNextCall QViewValidAsLongMoonIsTheRightPhase Some of these could be enforced by asserts, some could be just for documenting the issue. Anyway, just an idea :-) Cheers, Jędrek ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On terça-feira, 17 de outubro de 2017 08:28:54 PDT Marc Mutz wrote: > On 2017-10-10 14:49, Thiago Macieira wrote: > > == QStringView == > > * NEVER return QStringView (but QRegularExpression wants to) > > ** Consequence of "never return a reference" (but containers do) > > ** Lifetime issues > > > > auto s = lineedit.text().left(n); > > s valid? > > > > * We can be flexible on having exceptions: > > ** The API needs to be specifically designed for dealing with > > references > > ** Clear naming, such as QRegularExpression::captureView() > > > > Discussion not finished > > I certainly hope so, because the above does not make any sense. See my > talk at QtWS. Returning QStringView is not different from c.begin() or > str.data(). You need to document the lifetime of the data, that's it. Indeed, docs and proper documentation naming is required. We just concluded something we already knew: we need to avoid surprises. So when there's no benefit to returning QStringView, return QString. > In fact, I'm slowly moving to the conclusion that APIs should, in > general, not be formulated in terms of owning containers, except, maybe, > in areas where data is typically shared between classes, but even then > only in addition, as an extension. In Sean Parent's terms: "Goal: no raw > containers". Classes should accept and return views, and use whatever > data structure is most efficient for them, internally. A prime example > of the cleanup this provides is QRegion::begin/end(). Before you had to > call .rects(), forcing a memory allocation for the common case where the > region is just one rectangle. Not only is begin()/end() more efficient, > it's also easier to use: I don't doubt it. But, again, case-by-case basis. The performance improvement would be very nice to have, but that needs to be coupled with the API complexity and the not painting ourselves into a corner should we later decide to change internals. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On 2017-10-10 14:49, Thiago Macieira wrote: == QStringView == * NEVER return QStringView (but QRegularExpression wants to) ** Consequence of "never return a reference" (but containers do) ** Lifetime issues auto s = lineedit.text().left(n); s valid? * We can be flexible on having exceptions: ** The API needs to be specifically designed for dealing with references ** Clear naming, such as QRegularExpression::captureView() Discussion not finished I certainly hope so, because the above does not make any sense. See my talk at QtWS. Returning QStringView is not different from c.begin() or str.data(). You need to document the lifetime of the data, that's it. In fact, I'm slowly moving to the conclusion that APIs should, in general, not be formulated in terms of owning containers, except, maybe, in areas where data is typically shared between classes, but even then only in addition, as an extension. In Sean Parent's terms: "Goal: no raw containers". Classes should accept and return views, and use whatever data structure is most efficient for them, internally. A prime example of the cleanup this provides is QRegion::begin/end(). Before you had to call .rects(), forcing a memory allocation for the common case where the region is just one rectangle. Not only is begin()/end() more efficient, it's also easier to use: for (auto rect : region) { ... } vs. for (auto rect : region.rects()) { ... } // oops, detach const auto rects = region.rects(); for (auto rect : rects) { ... } // OK we even had code that did if (region.rectCount() == 1) doSomethingWith(region.boundingRect()): else Q_FOREACH(QRect r : region.rects()) doSomethingWith(r); presumably because the memory allocation made itself heard there. When this is done throughout the code base, Qt will become easier to use, and more efficient, and the pattern will be as imbued into developer's brains as is being()/end() now. And there's always static checkers for the odd error. Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
> (4x difference measured). wow, good to know. --- Jean-Michaël Celerier http://www.jcelerier.name On Tue, Oct 10, 2017 at 3:33 PM, Thiago Macieirawrote: > On Tuesday, 10 October 2017 15:04:29 CEST Jean-Michaël Celerier wrote: > > > ** Wrapping std::{unordered_}map may be acceptable > > > > Hmmm... from these benchmarks, QHash seems to regularly beat > > std::unordered_map so is it really worth it ? > > => https://tessil.github.io/2016/08/29/benchmark-hopscotch-map.html > > The motivation for change is not performance, but security. While we don't > think Qt applications are particularly susceptive to HashDoS attacks, our > approach here is "we can fix this, we may as well do it". > > The reason I'm benchmarking and suggesting SipHash-1-2 instead of the > standard > SipHash-2-4 is to avoid a big performance regression. > > > Besides, with the Qt implementation the performance is more-or-less > > consistent across platforms ; if it were to use > > std containers with moderately advanced algorithms, there could be much > > more differences depending on the various implementations > > (the worse offender being std::regex... these damn things just don't work > > the same on any platform). > > We actually have VERY different performance numbers across platforms. QHash > currently uses the CRC32 instructions on x86 and ARM, which means the > peformance can change significantly (4x difference measured). The same > applies > to the fixed version: the AES instructions are 5x faster than SipHash. > > > More generally, since all these containers are header-only due to their > > templated nature, wouldn't it be interesting and benefiting to the > greater > > C++ community to > > spin them off in their own small header-only utility library ? > > That's one big concern for a Qt6 QHash that wraps std:unordered_map. We'll > need to see what happens. > > > Having an explicit choice between COW and no-COW would be valuable in > many > > places where people don't want to bring large stuff like whole QtCore but > > where a few headers are OK imho; > > offering facades to std:: types with easy, readable Qt-like APIs would > also > > be quite nice (ideally with a set of standard-compliant typedefs, eg > > qt::hash_map... one can dream :p). > > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel Open Source Technology Center > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development > ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Tuesday, 10 October 2017 15:04:29 CEST Jean-Michaël Celerier wrote: > > ** Wrapping std::{unordered_}map may be acceptable > > Hmmm... from these benchmarks, QHash seems to regularly beat > std::unordered_map so is it really worth it ? > => https://tessil.github.io/2016/08/29/benchmark-hopscotch-map.html The motivation for change is not performance, but security. While we don't think Qt applications are particularly susceptive to HashDoS attacks, our approach here is "we can fix this, we may as well do it". The reason I'm benchmarking and suggesting SipHash-1-2 instead of the standard SipHash-2-4 is to avoid a big performance regression. > Besides, with the Qt implementation the performance is more-or-less > consistent across platforms ; if it were to use > std containers with moderately advanced algorithms, there could be much > more differences depending on the various implementations > (the worse offender being std::regex... these damn things just don't work > the same on any platform). We actually have VERY different performance numbers across platforms. QHash currently uses the CRC32 instructions on x86 and ARM, which means the peformance can change significantly (4x difference measured). The same applies to the fixed version: the AES instructions are 5x faster than SipHash. > More generally, since all these containers are header-only due to their > templated nature, wouldn't it be interesting and benefiting to the greater > C++ community to > spin them off in their own small header-only utility library ? That's one big concern for a Qt6 QHash that wraps std:unordered_map. We'll need to see what happens. > Having an explicit choice between COW and no-COW would be valuable in many > places where people don't want to bring large stuff like whole QtCore but > where a few headers are OK imho; > offering facades to std:: types with easy, readable Qt-like APIs would also > be quite nice (ideally with a set of standard-compliant typedefs, eg > qt::hash_map... one can dream :p). -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
On Tuesday, 10 October 2017 14:49:48 CEST Thiago Macieira wrote: > * They'd all need to be inline and some could be big Missing context here: this was about making them templated so they could work on std::string and other string-like types. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QtCS 2017 QtCore sessions
> ** Wrapping std::{unordered_}map may be acceptable Hmmm... from these benchmarks, QHash seems to regularly beat std::unordered_map so is it really worth it ? => https://tessil.github.io/2016/08/29/benchmark-hopscotch-map.html Besides, with the Qt implementation the performance is more-or-less consistent across platforms ; if it were to use std containers with moderately advanced algorithms, there could be much more differences depending on the various implementations (the worse offender being std::regex... these damn things just don't work the same on any platform). More generally, since all these containers are header-only due to their templated nature, wouldn't it be interesting and benefiting to the greater C++ community to spin them off in their own small header-only utility library ? Having an explicit choice between COW and no-COW would be valuable in many places where people don't want to bring large stuff like whole QtCore but where a few headers are OK imho; offering facades to std:: types with easy, readable Qt-like APIs would also be quite nice (ideally with a set of standard-compliant typedefs, eg qt::hash_map... one can dream :p). Best, --- Jean-Michaël Celerier http://www.jcelerier.name On Tue, Oct 10, 2017 at 2:49 PM, Thiago Macieirawrote: > [we combined the main and containers session; we did not have time for > QIODevice] > > == Intro == > Suggested topics: > * QIODevice for Qt 6 > * adding std::hash for Qt types > * expanding the hash seed to 64- or 128-bit > > Move to the containers session: > * use qssize_t > > Quick conclusions: > * QRandomGenerator and providing a PRNG of good quality (Mersenne Twister > or > Chacha20) > ** Yes if our compilers support > * hashing function update: > ** Use SipHash-1-2, benchmark 32-bit SipHash > ** See if Allan is interested in implementing with ARM AES > > == Use of standard C++ API == > > We will not add compilers that are worse than what we have today. > * If all the compilers we have support things like std::mersenne_twister, > then > all will > * We can add hard-fail configure test > * Should we start migrating from QSharedPointer to std::shared_ptr? > ** Deprecate > ** Deprecate QScopedPointer > * What about API from C++17/20 that we'd like to use? > ** Try to backport the API into a QtPrivate namespace (if it's been > standardised) unless we want to add significant functionality a la > QStringView > ** If it's not standardised yet, use Qt-style naming > * API naming > ** std:: API naming is subtly different from Qt API (hopefully nothing > that is > confusing or misleading) > ** We could try to create wrappers (container.empty() → > container.isEmpty()) > > == Modifiers vs getters for QString/QStringView/QByteArray == > We don't want people to write: > str = std::move(str).simplified() > We want instead: > str.simplify() > > So we want to add the full set of modifiers. > > Do we want to add freestanding functions that may operate on std::string > and > other string types? > * Like qSimplify() > * Polluting namespace > * They'd all need to be inline and some could be big > * freestanding brings in ADL and could introduce unexpected isues > * We think members are cleaner and we don't want to add these > > * However, we already have some of those! qStartsWith > ** Global namespace *and* documented > ** foo.startsWith(bar) vs qStartsWith(foo, bar) > ** Same conclusion, probably mark \internal, namespace them > *** But review the changes to see what our arguments were on making them > public > > == QStringView == > * NEVER return QStringView (but QRegularExpression wants to) > ** Consequence of "never return a reference" (but containers do) > ** Lifetime issues > auto s = lineedit.text().left(n); > s valid? > * We can be flexible on having exceptions: > ** The API needs to be specifically designed for dealing with references > ** Clear naming, such as QRegularExpression::captureView() > > Discussion not finished > > == Containers == > You cannot have all three: > # Implicit sharing > # Performance > # Data-compatibility with std:: containers > > QList: > * [https://codereview.qt-project.org/194984 QUIP 9] > > Conclusions: > * If we have QStringView, QArrayView, QByteArrayView, we don't need > fromRawData() > * We use qssize_t everywhere > ** Check if we want to rename it to "qssize" (bikeshed warning!) : https:// > codereview.qt-project.org/#/c/208050/ > * Investigate C++ contract assertions > > Containers relevant: > * QArrayData-based containers: QString, QByteArray, QVector > ** Backed by the same template implementation (QArrayDataPointer) > ** They grow to 3*sizeof(void*): {d pointer, begin pointer, qssize_t }; > ** Implementations: > template using QVector = QVectorImplementation RefCounted>; > template using QExclusiveVector = QVectorImplementation NotRefCounted>; > > QExclusiveVector v; > v.resize(1024); > auto ptr = v.data(); > // instead of: auto
[Development] QtCS 2017 QtCore sessions
[we combined the main and containers session; we did not have time for QIODevice] == Intro == Suggested topics: * QIODevice for Qt 6 * adding std::hash for Qt types * expanding the hash seed to 64- or 128-bit Move to the containers session: * use qssize_t Quick conclusions: * QRandomGenerator and providing a PRNG of good quality (Mersenne Twister or Chacha20) ** Yes if our compilers support * hashing function update: ** Use SipHash-1-2, benchmark 32-bit SipHash ** See if Allan is interested in implementing with ARM AES == Use of standard C++ API == We will not add compilers that are worse than what we have today. * If all the compilers we have support things like std::mersenne_twister, then all will * We can add hard-fail configure test * Should we start migrating from QSharedPointer to std::shared_ptr? ** Deprecate ** Deprecate QScopedPointer * What about API from C++17/20 that we'd like to use? ** Try to backport the API into a QtPrivate namespace (if it's been standardised) unless we want to add significant functionality a la QStringView ** If it's not standardised yet, use Qt-style naming * API naming ** std:: API naming is subtly different from Qt API (hopefully nothing that is confusing or misleading) ** We could try to create wrappers (container.empty() → container.isEmpty()) == Modifiers vs getters for QString/QStringView/QByteArray == We don't want people to write: str = std::move(str).simplified() We want instead: str.simplify() So we want to add the full set of modifiers. Do we want to add freestanding functions that may operate on std::string and other string types? * Like qSimplify() * Polluting namespace * They'd all need to be inline and some could be big * freestanding brings in ADL and could introduce unexpected isues * We think members are cleaner and we don't want to add these * However, we already have some of those! qStartsWith ** Global namespace *and* documented ** foo.startsWith(bar) vs qStartsWith(foo, bar) ** Same conclusion, probably mark \internal, namespace them *** But review the changes to see what our arguments were on making them public == QStringView == * NEVER return QStringView (but QRegularExpression wants to) ** Consequence of "never return a reference" (but containers do) ** Lifetime issues auto s = lineedit.text().left(n); s valid? * We can be flexible on having exceptions: ** The API needs to be specifically designed for dealing with references ** Clear naming, such as QRegularExpression::captureView() Discussion not finished == Containers == You cannot have all three: # Implicit sharing # Performance # Data-compatibility with std:: containers QList: * [https://codereview.qt-project.org/194984 QUIP 9] Conclusions: * If we have QStringView, QArrayView, QByteArrayView, we don't need fromRawData() * We use qssize_t everywhere ** Check if we want to rename it to "qssize" (bikeshed warning!) : https:// codereview.qt-project.org/#/c/208050/ * Investigate C++ contract assertions Containers relevant: * QArrayData-based containers: QString, QByteArray, QVector ** Backed by the same template implementation (QArrayDataPointer) ** They grow to 3*sizeof(void*): {d pointer, begin pointer, qssize_t }; ** Implementations: template using QVector = QVectorImplementation; template using QExclusiveVector = QVectorImplementation ; QExclusiveVector v; v.resize(1024); auto ptr = v.data(); // instead of: auto ptr = const_cast(v.constData()) QVector v2 = std::move(v); v = std::move(v2); * QStringView * QHash, QMap ** Wrapping std::{unordered_}map may be acceptable ** Would we want to use qHash as the HashFunction with std::unordered_map? -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development