[Development] Deprecation/removal model going into Qt 6
Giuseppe D'Angelo
giuseppe.dangelo at kdab.com
Mon Jun 3 15:26:36 CEST 2019
Il 03/06/19 13:34, Kevin Kofler ha scritto:
> Giuseppe D'Angelo via Development wrote:
>
>> Il 03/06/19 00:08, Kevin Kofler ha scritto:
>>> What you call "obsolete functionality" is functionality that existing
>>> code relies on and rightfully expects to remain there.
>>
>> Rightfully? By what right exactly?
>
> APIs in libraries are meant to be used. I consider it an entirely reasonable
> expectation by developers using the APIs that they will not be removed under
> them because the library developers consider them "obsolete". Imagine the
> chaos if Intel or AMD decided to remove some random "obsolete" x86
> instructions from their CPUs! x86 has kept backwards compatibility with
> every single instruction for more than 30 years. This is the standard
> software libraries should be held to, too.
Nice try: https://rationalwiki.org/wiki/Straw_man#Forms
Specifically: moving the focus from a GUI framework's API to a
foundational computer architecture design (which must provide much
stronger guarantees).
Also, please name me 3 GUI frameworks that have not broken APIs for 30
years.
Also also, please name me 3 libraries that have not broken APIs for the
30 years.
Also also also, at least in the x86-64 world, major "API breaks" at the
assembly level have already somehow occurred. And that's an architecture
that has been around for less than 20 years.
>>> I'd rather get fewer (or even no) new features than losing existing ones.
>>
>> How is this even an argument? Qt will need to evolve and acquire
>> features to remain competitive. Again, development bandwidth is finite:
>> either the overall quality decreases or some things have to get dropped.
>
> Qt has long reached a point where it can be considered complete. Its main
> selling point is portability to many different platforms rather than some
> specific feature. Additional features don't necessarily need to be in the
> main Qt library, but can be in community-developed addons such as KDE
> Frameworks or such as the many third-party Qt-based Free Software libraries
> out there. (They can also be in Qt-Company-developed Qt Solutions if there
> is manpower left for that.)
>
> Qt has also become larger and larger over time (despite the removal of APIs
> considered obsolete).
The removal of APIs in Qt 5 lifetime has been mostly "limited" to
dropping entire obsolete modules. No cleanup has been done to deprecated
API inside a module. Qt 6 wants to do that, and the point of this thread
is how to minimize the pain.
> Just compare the size of the Qt 3 tarball with the
> size of the Qt 5 monolithic tarball. This is not the result of keeping old
> APIs around, but of feature creep.
"Creep" is questionable; and anyhow off-topic.
> So I disagree with the assertion that Qt needs more features to remain
> competitive.
And I disagree with this. And even assuming to stop adding new feature,s
the _current_ feature set may need refactoring and redesigns, which may
mean API breaks.
>>> See also Boudewijn Rempt's blog post on the subject:
>>> https://valdyas.org/fading/hacking/happy-porting/
>>
>> I agree with the principle (API breaks are painful), but I strongly
>> disagree with the idea that no API breaks can ever possibly happen. And
>> the specific example is a terrible one to make a point as the resulting
>> API break is trivial to work around (I defined such breakages
>> "scriptable").
>
> The Q_FOREACH to ranged for change is not as easy to port to as people
> think, because there are at least 2 pitfalls when porting to ranged for:
> 1. you have to add qAsConst or equivalent or you will be deep-copying your
> implicitly-shared CoW container,
> 2. code that was changing the container during the iteration, which worked
> just fine with Q_FOREACH (because the iteration would still be over the
> original unchanged container), will now crash without warning. Even
> qAsConst will not help you get a warning or error for it, because it only
> constifies the reference for the ranged for itself and not for the code
> within it.
>
> This is effectively deprecating a safe construct for an unsafe one.
This is not the intended port, because it's not scriptable. Moving to a
range-based for is the long-term solution, but that requires checking
all usages.
The intended _scriptable_ solution is
1) copy and paste Q_FOREACH from qglobal.h into a central header of your
project
2) rename all occurrences it to MY_FOREACH
3) done
What's the difference, then? For your code, minimal (just use another
macro). But for Qt, that it stops supporting Q_FOREACH, teaching its
usage, and advocating for it.
>>> An array of pointers is the most efficient data structure in practice
>>> (operations are at most O(n)), dropping it in favor of an O(mn) data
>>> structure (where m = sizeof(T)) such as QVector is a pessimization. And
>>> QList also has the prepend optimization that makes most prepends even
>>> O(1) rather than O(n). I don't see why almost everybody hates it.
>>
>> As written, the above makes no sense, as it looks like you're comparing
>> apples and oranges: time complexities against space complexities.
>
> I'm speaking exclusively of time complexities. The space only matters when
> it goes into the formula for the time, which is the case for QVector.
>
> QList::insert and QList::removeAt have O(n) time complexity.
> QVector::insert and QVector::removeAt have O(mn) time complexity.
>
> QList::prepend has O(1) amortized and O(n) worst case time complexity.
> QVector::prepend has O(mn) (always!) time complexity.
>
> If you are dealing with a large class or struct, e.g. 800 bytes, then the
> QVector operations are 100 times slower than the QList ones!
This is just *false*. You're (deliberately?) ignoring the cost of memory
allocations and deallocations, hiding them in big-O constants, something
I already warned you about. I won't then waste time debunking this.
>>> For the "unnecessary" part, because Qt has been working fine without
>>> QString SSO for years.
>>
>> Nice try: https://en.wikipedia.org/wiki/Appeal_to_tradition
>
> This is not an appeal to tradition, but to practical experience. QString is
> working well in thousands of software packages now.
Another appeal to tradition.
> Of course, that doesn't
> imply that it is not possible to do better, in theory. But is this
> optimization worth the trouble of breaking the ABI?
Yes.
(Keep in mind that my
> argument is that Qt 6 should either be source&binary-compatible with Qt 5
This won't happen.
>> Second, string classes in all major C++ libraries and frameworks are
>> deploying SSO *because* it is a performance win.
>
> SSO is a clear performance win for std::string because std::string is NOT
> CoW (in fact, g++'s implementation used to be, but it was dropped because
> some obscure "clarification" in C++11 is interpreted as forbidding it).
The "obscure" clarification is called exception safety.
> So
> you have to deep-copy anyway, and SSO saves the allocation. But SSO bypasses
> CoW, so is only a win on the current architectures with ridiculously slow
> atomics and fast bulk copies. If atomics ever get optimized in a new CPU
> architecture, you'll wish the old QString back.
CoW and SSO are orthogonal optimizations. folly's fbstring has *both*.
>>> For the "probably also counterproductive" part:
>>> * Because there are surely architectures or environments where copying
>>> 256 bytes (or whatever the SSO max length actually is)
>>
>> This is a straw man argument, specifically an exaggeration.
>>
>> At some QtCS Thiago was talking about 23-24 QChars, i.e. 48 bytes, plus
>> a couple of pointers or so, to bring it to 64 bytes (~ a cacheline).
>
> "or whatever the SSO max length actually is". So 64 bytes it is. Still 8
> times more than before. This is only faster because current architectures
> suck at atomics.
Hey, I somehow assumed that you liked the 30 years old compatible
assembly? Guess what's the price to pay for being compatible with an
overly-strict and expensive model for atomics?
>> This thread was about managing API breaks. Adding SSO to QString is not
>> meant to be an API break (*). Please stop derailing the thread.
>>
>> (*) Emphasis on _meant_, because obviously it yields observable side
>> effects.
>
> This thread was also about managing ABI breaks, which QString SSO definitely
> is.
Qt 6 will break ABI.
This thread is about API breaks. I should know, I've started it.
--
Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4329 bytes
Desc: Firma crittografica S/MIME
URL: <http://lists.qt-project.org/pipermail/development/attachments/20190603/5880cb84/attachment.bin>
More information about the Development
mailing list