On Monday, 9 November 2020 08:16:51 PST Giuseppe D'Angelo via Development wrote: > >> 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.
If we don't need the memset-as-initialisation, we can relax the "primitive type" to an actual C++ category: trivially-copyable type. We're already renaming the Q_MOVABLE_TYPE category to align with future standard direction and calling it Q_RELOCATABLE_TYPE. A trivially copyable class type has (http://eel.is/c++draft/class.prop#1): * a non-deleted, trivial copy constructor or move constructor * a non-deleted, trivial destructor This differs from relocatability by requiring the trivial destructor, which means we can forego calling it in QMetaType (in containers I'd expect the loop simply expands to no code). A trivially-copyable class need not have a trivial constructor (http://eel.is/ c++draft/class.default.ctor#3), but we can add that requirement too, which would make our requirement even stronger, at trivial type. Note that a trivial constructor does not imply the zero-initialised object is equivalent to the default construction type. This example from Peppe's other email is a trivial type and yet its default (constexpr) construction is not all zeroes: struct C { int A::* ptr; }; see <https://gcc.godbolt.org/z/81dacG>. In fact, I think pointer-to-member-object is the only example of a trivial construction to non-zero-bits in either ABI that matters. For everything else, a memset-to-zero construction will match the default (trivial, constexpr) constructor. And for PMOs, it will create a valid if non-default representation. So my recommendation is: 1) deprecate Q_PRIMITIVE_TYPE and rename to Q_TRIVIAL_TYPE 2) *not* use memset-to-zero construction anywhere #2 implies changing QPodArrayOps, which does use memset, to use a loop calling the default constructor. Two of the four compilers do optimise that into a call into memset: https://gcc.godbolt.org/z/Ks3M5h. And there's nothing the ICC team likes to work on more than losing on a benchmark. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering _______________________________________________ Development mailing list [email protected] https://lists.qt-project.org/listinfo/development
