[Development] What's Q_PRIMITIVE_TYPE for?

Giuseppe D'Angelo giuseppe.dangelo at kdab.com
Mon Nov 9 10:25:50 CET 2020


I have been wondering whether Q_PRIMITIVE_TYPE could be phased out and 
its support removed (kept for SC, but effectively it simply becomes 
synonymous for Q_MOVABLE_TYPE).

First and foremost, there seems to be disagreement on what "primitive 
type" means. From the docs:

> Q_PRIMITIVE_TYPE specifies that Type is a POD (plain old data) type with no constructor or destructor, or else a type where every bit pattern is a valid object and memcpy() creates a valid independent copy of the object.

With this definition in mind, why is QUuid primitive, QVector3D 
primitive, but QSize not primitive? They all are non-trivial types, they 
all have default constructors that set their contents to 0. Which one is 
correct? Can the others be changed while keeping BC?

Then: is this definition actually exploited anywhere?

* Regarding construction: containers are required to value-initialize 
their contents (e.g. when resizing), so the optimization of "does not 
have a constructor" is not necessary at all. Is the reason why we carry 
Q_PRIMITIVE_TYPE that we plan to add functions to manipulate containers 
that do not initialize primitive types instead? (*)

* Regarding destruction: right now containers do use the primitive trait 
only with one purpose: to avoid calls to a type's destructor. Is such an 
optimization even still needed? Types with an empty destructor (trivial, 
or inline and empty, etc.) already emit no code on GCC / Clang under -Og 
(the default for debug builds), and no code under any compiler under -O2 
(release builds). GCC even removes calls to library functions such as 
std::destroy_n under -Og.

(So, something we could already do is just call the destructor 
unconditionally, removing some unnecessary complexity from our containers.)

The only other place that cares about primitive types is QMetaType, 
which uses this information to set the "NeedsConstruction" or 
"NeedsDestruction" type flags. But these type flags are never used 
anywhere inside of Qt; QMetaType value/copy/move constructs, and 
destructs, every type.

(*) To see this in another way: it's an interesting approach to have 
types for which default construction does initialize, but also Qt 
specific "library" way to create uninitialized objects (in Qt containers).

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/20201109/0661328f/attachment.bin>

More information about the Development mailing list