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.dang...@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

Attachment: smime.p7s
Description: Firma crittografica S/MIME

_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to