On Friday 30. March 2012 13.54.06 ext Marc Mutz wrote: > 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
Then the only real problem I see is: QVarLengthArray<QUuid> array; array.resize(1); currently this is always true: array.at(0).isNull() == QUuid().isNull() with new definition it may be something else. It is not big deal, just is a bit unintuitive but if you take QFlags instead QUuid then it may break existing code in a nasty way, for example: QVarLengthArray<QFlags> array(1); ... array[0] |= MyFlag; How an user of QFlags can know if it is marked as primitive or not? The class has a ctor so from c++ perspective it is not a POD. Should he check source code? We do not have documentation for such things and searching for QTypeInfo specialization is not an option (it may placed everywhere and hidden in a macro). Dumping values of QTypeInfo<QFlags>, which is internal, is not nice. So how can he be safe in this case? Only by reinitializing values again: QVarLengthArray<QFlags> array(1); array[0] = QFlags(); ... array[0] |= MyFlag; So I'm afraid that marking QFlags as primitive may decrease performance in global picture. I believe that it is not a nice API. I will keep my -1 because it is what I think about it. In the end, you can always override it, I'm fine with that ;-) Cheers, Jędrek
_______________________________________________ Development mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/development
