[Development] Qt 5.5.0 header diff: QtCore.diff
Olivier Goffart
olivier at woboq.com
Tue Jun 9 12:10:02 CEST 2015
On Monday 8. June 2015 17:57:23 Thiago Macieira wrote:
> On Monday 08 June 2015 15:58:23 Olivier Goffart wrote:
> > > > There is no reason to stop improving qmetatype.
> > >
> > > The qFatal was there for a good reason.
> >
> > It was there for a good reason for the existing flags.
> > But for new flags of course it does not make sens.
>
> It did make sense: the idea was that registering new flags would cause the
> very incompatibility we're seeing here. I'm not entirely convinced that we
> discussed all scenarios at QtCS, so I'm still skeptical about allowing the
> IsGadget flag. I insist that we \omitvalue for now, until we understand the
> consequences better.
No, the qFatal is there because a change in the other flags like the
MovableType is binary incompatible.
A change in the IsGadget flag is fine.
Old code did not need this flag. And code that relies on it requires anyway
that the code that register the types register the isGadget flag.
Even if one could build a complicated use case that breaks, it would be very
unlikely to happen.
And any change is dangerous. When we fix any small bug, there can always be
applications that breaks because it was relying on the bug for something.
Anyway, let us summarize the "problem" in that case.
In Qt <= 5.4, QtLocation was using QML Private API to basically creates
QObject wrapper around QGeoCoordinate so it can be exposed in QML. But in Qt
5.5, one does not need private API, everybody can expose value types to QML
just by adding Q_GADGET to it and registering Q_PROPERTY or Q_INVOKABLE.
So QGeoCoordinate became a Q_GADGET. But for QML to be able to take advantage
of it, the type needs to be registered with the QMetaType::IsGadget flag. This
is automatic. But if the metatype is registered by code compiled with Qt 5.4
or before, the IsGadget flag is not present.
This is what is happening in a application that was compiled against Qt 5.4,
QGeoCoordinate was used in signal and slot and registered as a metatype by the
application. QMetaType will detect the difference in the flags on the second
registration and do a qFatal.
The solution is obviously not to do a qFatal, but take the new flags in
addition. And then everything works as expected.
Now the problem is: could there be code that relies in IsGadget that is run
and that the type is only registered by "old" code but not by new code. i.e:
could loading an old plugin compiled with an old code suddenly break a new
application using these new feature.
In theory this is possible, but in practice I don't think this will ever
happen.
Let's suppose an application called App 1.0 which has this code:
mystruct.h:
struct MyStruct {
int myValue;
};
Q_DECLARE_METATYPE(MyStruct);
myitem_p.h
class MyItem : public QObject {
Q_OBJECT
Q_INVOKABLE extractValue(const QVariant &v) {
return qvariant_cast<MyStruct>(v).myValue;
}
};
foo.qml:
MyItem {
function foobar(someObject) {
return extractValue(someObject.myStructProperty);
}
}
someObject is an object coming from a plugin which has a property
myStructProperty of type MyStruct.
Now, App 1.1 gets released and they simplify the code:
mystruct.h:
struct MyStruct {
Q_GADGET;
Q_PROPERTY(int myValue MEMBER myValue)
public:
int myValue;
};
foo.qml:
MyItem {
function foobar(someObject) {
// now that myStruct is a Q_GADGET i don't need the helper
return someObject.myStructProperty.myValue;
}
}
Then yes, if the MyStruct was only registered by the plugin we get a binary
compatibility problem in the application. But this is a problem for the
application, not Qt. And the solution is to make sure that MyStruct is
registered by manually registering it using qRegisterMetaType
> And it's not just the flag. I'm not convinced about the template detection
> either. You had to apply two late fixes to the detection so that we wouldn't
> break source compatibility or create unnecessary warnings.
Yes, I had to apply fixes after the beta was released and it got tested in the
wild. But is that not what beta releases are for?
> > > The freeze stays: no new flags in QMetaType until Qt 6, no more messing
> > > with the template black magic.
> >
> > You can't mandate that.
>
> Yes, I can. As the maintainer, I have the authority and mandate to oversee
> the changes to the module I maintain and that includes blocking changes I
> am unsatisfied with.
>
> A mailing list consensus can overrule me, as can the Chief Maintainer.
>
> We stay frozen until further notice. If you have new flags you want to
> propose, you can do it, but we'll need a mailing list discussion before the
> change is allowed.
Well, then it will be reviewed as usual.
There are few improvements that can be done to QMetaType that we were
discussing at the summit, like the ability to modify list types (append and
such) or including some of the C++11 features. I bet one can simplify
qmetatype.h when we require C++11's decltype and proper SFINAE rules
More information about the Development
mailing list