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
