Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-09 Thread Olivier Goffart
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_castMyStruct(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




Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-09 Thread Thiago Macieira
On Tuesday 09 June 2015 12:10:02 Olivier Goffart wrote:
 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 yet it did happen, or we wouldn't be having this conversation. If Alex 
could do it in qtconnectivity, why can't others do it in other circumstances?

 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.

The problem is the associated risk because this code is complex and varies 
depending on factors we usually don't think about. This isn't about your 
standard class that operates on data.

 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.

And register the metatype for the Q_GADGET, which it hadn't done before.

My point is that you had not thought of this when you wrote the feature. 
Therefore, there shall be no more such features without major discussion 
because we are failing to see all the possible consequences. And I am not 
convinced yet we've found them all.

What are the consequences of overriding the flag and the metatype? Could it be 
that the user did intentionally break compatibility, yet failed to recompile 
one module? That's what the qFatal was there for: a reminder. We're removing 
it.

  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 problem is the precedent. We are not finding everything and this code is 
extremely complex. The more we add to it, the more complex it becomes 
(exponentially so).

 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

We will have to discuss each modification in the mailing list.

And note that replacing the rules with C++11 simpler rules may have side-
effects too, so you should not simplify for the sake of simplification.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-08 Thread Thiago Macieira
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.

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.

  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.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-08 Thread Olivier Goffart
On Saturday 6. June 2015 11:17:30 Thiago Macieira wrote:
 On Friday 05 June 2015 10:11:28 Frederik Gladhorn wrote:
 
 
 I can't tell if the qmetatype.h template magic is binary compatible or not.
 As evidenced by a recent push [1] about the IsGadget flag, it isn't.
 
 I'm going to put a stop to this. qmetatype.h template magic is now frozen as
 of Qt 5.5 and until Qt 6.0, aside from bugfixes or pure additions that do
 not modify existing template classes.
 
 [1] https://codereview.qt-project.org/113652

The problem here is the qFail. We can just remove the qFail in this case (what 
the patch does) and we will be fine.

There is no reason to stop improving qmetatype.

   Q_DECLARE_FLAGS(LoadHints, LoadHint)
  
  +Q_FLAG(LoadHint)
  +Q_FLAG(LoadHints)
 
 Do we need both Q_FLAG? That looks like a mistake.


The code was just moved from Q_FLAGS to Q_FLAG.  Both were there before and I 
kept it like that.

It cannot really be changed otherwise code like 
staticQtMetaObject.indexOfEnumerator(LoadHint) or 
staticQtMetaObject.indexOfEnumerator(LoadHints) will break.

The use of Q_ENUMS and Q_FLAGS with QFlags types is not really consistent 
within Qt.  

-- 
Olivier 

Woboq - Qt services and support - http://woboq.com - http://code.woboq.org

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-08 Thread Olivier Goffart
On Monday 8. June 2015 09:34:30 Thiago Macieira wrote:
 On Monday 08 June 2015 11:28:48 Olivier Goffart wrote:
  On Saturday 6. June 2015 11:17:30 Thiago Macieira wrote:
   On Friday 05 June 2015 10:11:28 Frederik Gladhorn wrote:
   
   
   I can't tell if the qmetatype.h template magic is binary compatible or
   not.
   As evidenced by a recent push [1] about the IsGadget flag, it isn't.
   
   I'm going to put a stop to this. qmetatype.h template magic is now
   frozen
   as of Qt 5.5 and until Qt 6.0, aside from bugfixes or pure additions
   that
   do not modify existing template classes.
   
   [1] https://codereview.qt-project.org/113652
  
  The problem here is the qFail. We can just remove the qFail in this case
  (what the patch does) and we will be fine.
  
  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.
 
 The freeze stays: no new flags in QMetaType until Qt 6, no more messing with
 the template black magic.

You can't mandate that.

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-08 Thread Thiago Macieira
On Monday 08 June 2015 11:28:48 Olivier Goffart wrote:
 On Saturday 6. June 2015 11:17:30 Thiago Macieira wrote:
  On Friday 05 June 2015 10:11:28 Frederik Gladhorn wrote:
  
  
  I can't tell if the qmetatype.h template magic is binary compatible or
  not.
  As evidenced by a recent push [1] about the IsGadget flag, it isn't.
  
  I'm going to put a stop to this. qmetatype.h template magic is now frozen
  as of Qt 5.5 and until Qt 6.0, aside from bugfixes or pure additions that
  do not modify existing template classes.
  
  [1] https://codereview.qt-project.org/113652
 
 The problem here is the qFail. We can just remove the qFail in this case
 (what the patch does) and we will be fine.
 
 There is no reason to stop improving qmetatype.

The qFatal was there for a good reason.

The freeze stays: no new flags in QMetaType until Qt 6, no more messing with 
the template black magic.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development


Re: [Development] Qt 5.5.0 header diff: QtCore.diff

2015-06-06 Thread Thiago Macieira
On Friday 05 June 2015 10:11:28 Frederik Gladhorn wrote:
 

I can't tell if the qmetatype.h template magic is binary compatible or not. As 
evidenced by a recent push [1] about the IsGadget flag, it isn't.

I'm going to put a stop to this. qmetatype.h template magic is now frozen as 
of Qt 5.5 and until Qt 6.0, aside from bugfixes or pure additions that do not 
modify existing template classes.

[1] https://codereview.qt-project.org/113652

 +++ b/src/corelib/plugin/qfactoryinterface.h
  Q_DECLARE_FLAGS(LoadHints, LoadHint)
 +Q_FLAG(LoadHint)
 +Q_FLAG(LoadHints)

Do we need both Q_FLAG? That looks like a mistake.

 +// ### Qt6: check if there's a better way
 +class QStringList : public QListQString
[...]
 -inline void sort(Qt::CaseSensitivity cs = Qt::CaseSensitive);
 -inline int removeDuplicates();

The above works only because:
 1) QStringList is not exported
 2) the functions in question are inlines

However, if someone derives from QStringList and exports a class, using MSVC, 
then this may be binary incompatible. See qvector_msvc.h.

I have not and will not investigate this further, so I don't know if this is 
real or not. If there's a bug reported on this, I will probably close it with 
you're committing too many mistakes (using MSVC and deriving from 
QStirngList).

The rest looks good, but I hope I didn't miss anything in the Q_DECL_NOTHROW, 
Q_DECL_OVERRIDE and Q_DECL_CONSTEXPR noise.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

___
Development mailing list
Development@qt-project.org
http://lists.qt-project.org/mailman/listinfo/development