[Development] Meaning of Q_PRIMITIVE_TYPE?

Marc Mutz marc.mutz at kdab.com
Fri Mar 30 13:54:06 CEST 2012


On Friday March 30 2012, Jedrzej Nowacki wrote:
> On Wednesday 28. March 2012 15.37.46 ext Marc Mutz wrote:
> > Hi,
> >
> > Over at http://codereview.qt-project.org/21518, we're discussing whether
> > QUuid is Q_PRIMITIVE_TYPE or only Q_MOVABLE_TYPE.
> >
> > The documentation of Q_DECLARE_TYPEINFO says Q_PRIMITIVE_TYPE means the
> > type is a POD, without constructors or destructors. According to that
> > definition, QUuid is not primitive. But neither would be QFixed and
> > QFlags, which have been marked primitive in the past.
> >
> > I think the intention of Q_PRIMITIVE_TYPE, and the way it is used in Qt,
> > is to mark types that act as ints do, ie. there's no class invariant, so
> > char[sizeof(type)] = { 0 } is equal to the default-constructed value,
> > uninitialised memory represents a valid value[1], and the object owns no
> > resources. It is in this sense that QFixed, QFlags and QUuid are
> > primitive types.
> >
> > [1] This doesn't hold for cups_option_t, btw, which is marked primitive,
> > but is a struct{char*a,*b;}, so uninitialised memory does not represent a
> > valid value, even though, technically, it's a POD.
> >
> > So I'd like to propose to extend the scope of Q_PRIMITIVE_TYPE to cover
> > such non-POD classes that are nevertheless close enough to PODs.
> >
> > That means:
> > 1a. memset(0, &t, sizeof(T)) constructs a valid object, and that object
> > is equal to T(), if T has a default constructor.
> > -alternatively-
> > 1b Any bit pattern represents a valid object (one that the dtor can be
> > called on).
> > 2. memcpy() creates a valid independent copy of the object
> > 3. The dtor doesn't need to be run.
> >
> > With 1a+2+3, primitiveness is a strict superset of PODness.
> >
> > If Jędrzej is right, though, and the intent was for primitive types to
> > not require initialisation, ie. the 1b alternative is used, PODness is no
> > longer sufficient for primitiveness. And cups_option_t must be downgraded
> > to movable.
> >
> > Looking at existing usage, I think 1a+2+3 comes closest to what everyone
> > thinks primitive types mean, so I'd like to update the docs accordingly.
> >
> > Opinions?
> >
> > Thanks,
> > Marc
>
> Hi,
>
>   I think that intent for primitive types was to mark POD types as docs
> say.
>
>  By removing '1b' requirement you will break or slowdown code that relays
> on that feature. For example:
> - QVarLengthArray - checkout docs for resize() -> not fixable, you need to
> accept slowdown (memset call)
> - QVariant - qvariant_p.h isNull detection -> fixable
>
>   The main problem appears when a "default" constructed value or
> uninitialized value has to be created.
>
>   As I said on the gerrit change, what you really need is something like
> canBeConstructedByMemsetItToZero :-)

Thanks for the QVarLengthArray use-case. Yes, that requires 1b.

I don't mind 1b. Both 1a and 1b definitions make QUuid primitive (which is 
where this discussion started). Since pointers are primitive and thus not 
initialised by QVarLengthArray, I'd be ok even with cups_option_t (pair of 
pointers) staying primitive.

So, does that mean you'll retract your -1?

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions



More information about the Development mailing list