[Development] HEADS UP: Don't use QList, use Q_DECLARE_TYPEINFO

Marc Mutz marc.mutz at kdab.com
Fri Jul 10 11:03:49 CEST 2015


Hi,

I'll never manage to eradicate inefficient QLists if people continue to add 
new ones :) So here are some things I'd like _everyone_ to watch out for in 
reviews and mercilessly -1:

- using QList
- not using Q_DECLARE_TYPEINFO

Let me qualify that a bit: QList<C> is a _very_ bad idea for virtually any C, 
because the minutest of mistakes (and the default behaviour _is_ a mistake) 
can render it utterly and unacceptably inefficient. I won't give you the whole 
story (google "QList harmful" for that), but never, ever use QList<C> 
*unless*:

- sizeof(C) == sizeof(void*) (*both* on 64 and 32-bit platforms!) _and_ C has
  been declared Q_MOVABLE_TYPE or Q_PRIMITIVE_TYPE
-or-
- the use is unescapable, because other parts of Qt use it (e.g. QVariant,
  QModelIndex).

The latter doesn't mean that you should _always_ use QList for QVariant or 
QModelIndex. If all you're doing is local to your class, then by all means use 
a QVector.

QVector is the correct default container. If you actually need list behaviour 
(ie. linked lists), use QLinkedList instead. It tends to be _faster_ than 
QList.

In private implementation, also consider using std::vector<C>, esp. if you 
never copy it and C is (explictly or implicitly) move-enabled. It typically 
produces up to 1KiB less executable code than QVector. *Per instantiation*.

If in *any* kind of doubt whether QList is acceptable, or any of your 
container choices, feel free to add me as a reviewer.

And please, whenever you add a new type (not just class, *any* type, incl. 
enums, but excluding QFlags (which are automatically primitive)), strongly 
consider Q_DECLARE_METATYPE with the appropriate flag (yes, even 
Q_COMPLEX_TYPE). About the only time this can be considered optional is for 
polymorphic classes. It should become second nature to Q_DECLARE_TYPEINFO.

It should be considered a _must_ to Q_DECLARE_TYPEINFO any type that is put 
into a QVector, QList or QVariant. In fact, my local copy enforces this at 
compile-time. I hope to push this work at some point, but of course, that 
means that each and every occurrence in Qt itself first needs to be fixed, and 
even then, we can only enable it as an opt-in to not break user code (even if 
it deserves to be broken).

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt Experts



More information about the Development mailing list