Hello,

There's another subtle case when your type has in-class member initializers - 
or whatever the name is - thus it's not primitive but it really could/should be 
and you want it to be: https://gcc.godbolt.org/z/3TP83f. This is something I 
accidentally discovered.

And I don't think that compilers are smart enough already to turn a for
loop that is filling with zeros into a memset, so we need the type info
for this. Or am I wrong?

When profiling, memcpy/memmove resulted into an AVX-based function call to some 
internal library function, memset might as well be similar (but not sure).
NB: for Movable types, we do not simply memset everything to zero, we call 
placement-new. It's not quite the same as what QPodArrayOps are doing, I 
believe.

--
Best Regards,
Andrei
________________________________
From: Development <[email protected]> on behalf of Giuseppe 
D'Angelo via Development <[email protected]>
Sent: Monday, November 9, 2020 5:16 PM
To: Lars Knoll <[email protected]>
Cc: Qt development mailing list <[email protected]>
Subject: Re: [Development] What's Q_PRIMITIVE_TYPE for?

Hello,

On 09/11/2020 11:33, Lars Knoll wrote:
>>> 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?
> If a type is relocatable, it’s default constructor memsets all bits of the 
> object to 0, the copy constructor just does a memcpy of those bits and the 
> destructor does nothing you can just as well mark the type as primitive.
>
> I think the fact that QSize is not marked primitive is a bug and should be 
> fixed. Fortunately, changing that does not affect ABI.
>> Then: is this definition actually exploited anywhere?
> It’s being used to select the QPodArrayOps for QList. The advantage it that 
> we in this case use memset() instead of constructors, and memcpy/memmove to 
> copy or move data.
>
> This does still make a difference compared to Q_RELOCATABLE_TYPE, where we 
> need to use a combination of memmove and copy constructors, and also need to 
> take care of at least basic exception safety when constructing items in the 
> list. For primitive types we can avoid both copy constructors and the 
> rollback handling for potential exceptions.

Thank you! This is what I missed. And indeed this is what is missing
from the Q_PRIMITIVE_TYPE documentation: the condition "every bit
pattern is a valid object" is necessary but not sufficient. It also
needs: "value construction sets all (non-padding) bytes to 0", which is
what gets actually exploited in the current code.

This explains why QSize isn't primitive: every bit pattern is a valid
QSize, but its default constructor sets the extents to -1. So you can't
build a QSize by allocating memory and memsetting it to 0.

And I don't think that compilers are smart enough already to turn a for
loop that is filling with zeros into a memset, so we need the type info
for this. Or am I wrong?


>> 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.
> This would actually be something to look into. We could avoid creating those 
> methods, and instead have a flag and in those cases the implementation in 
> QMetaType could simply use memset and memcpy.

To be honest, I don't see an advantage here, given QMetaType doesn't
need to "bulk" construct or destroy N objects but only 1, and it could
just call its constructor/destructor rather than short circuiting the
operations to memset/memcpy.


Thank you,
--
Giuseppe D'Angelo | [email protected] | 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

_______________________________________________
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to