Reputation: 941
I am currently migrating a huge project from Qt 4.x to 5.2.1, Everything has been rather good until this error, which I find incredibly confusing because its located at the Qt files, and I believe the solution must be applied somewhere else, not in the qglobal.h located at 5.2.1\mingw48_32\include/QtCore/qglobal.h. The error must be happening somewhere else.
Heres the error:
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qglobal.h:681:85: error: invalid application of 'sizeof' to incomplete type 'QStaticAssertFailure' enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, COUNTER) = sizeof(QStaticAssertFailure)} ^
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qglobal.h:686:47: note: in expansion of macro 'Q_STATIC_ASSERT' #define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) ^
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qobject.h:520:5: note: in expansion of macro 'Q_STATIC_ASSERT_X' Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro::Value, ^
Here's the piece of code in qglobal.h
// Intentionally undefined
template <bool Test> class QStaticAssertFailure;
template <> class QStaticAssertFailure<true> {};
#define Q_STATIC_ASSERT_PRIVATE_JOIN(A, B) Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B)
#define Q_STATIC_ASSERT_PRIVATE_JOIN_IMPL(A, B) A ## B
#ifdef __COUNTER__
#define Q_STATIC_ASSERT(Condition) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __COUNTER__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#else
#define Q_STATIC_ASSERT(Condition) \
enum {Q_STATIC_ASSERT_PRIVATE_JOIN(q_static_assert_result, __LINE__) = sizeof(QStaticAssertFailure<!!(Condition)>)}
#endif /* __COUNTER__ */
#define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition)
#endif
I have tried everything and have researched all about it, but didnt find a proper solution. I have wasted all day in this annoying piece of code. I hope someone can shed some light on the matter.
Thankyou very much.
EDIT: I searched for all the documents that included qglobal.h, but none of them make use of any assert funcion, so I dont know what could be triggering such error. Theres no way that the qglobal.h is wrong, so it must be something of the source code.
EDIT2: I managed to isolate the lines that trigger the error, apparently the compilation output gave more information than I thought, but it was so 'separated' that I thought it was a warning and had nothing to do. Here is the code from my application. The two commented lines are the ones that trigger the error. Sorry for my mistake.
bool ISPSModel::removeGraphics(GraphicsPrimitive* _gtr) {
for (int _i = 0; _i < ispss.size(); _i++) {
for (int _j = 0; _j < ispss[_i]->graphicsObjects.size(); _j++) {
if (ispss[_i]->graphicsObjects[_j] != _gtr)
continue;
if (ispss[_i]->graphicsObjects.contains(_gtr)) {
//beginRemoveRows(indexFromItem(ispss[_i]->m_item), _gtr->getData(DATA_ROLE).value<ISPSItem*>()->row(), _gtr->getData(DATA_ROLE).value<ISPSItem*>()->row());
//_gtr->getData(DATA_ROLE).value<ISPSItem*>()->remove();
ispss[_i]->removeGraphics(ispss[_i]->graphicsObjects[_j]);
endRemoveRows();
return true;
}
}
}
return false;
}
Its this part the one that causes the error:
value<ISPSItem*>()
Heres the other part of the compilation error that I had ignored, in case it can help:
..........\Qt5\5.2.1\mingw48_32\include/QtCore/qobject.h: In instantiation of 'T qobject_cast(QObject*) [with T = ISPSItem*]': ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:695:51: required from 'static T QtPrivate::QVariantValueHelper::object(const QVariant&) [with T = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:101:37: required from 'static ReturnType QtPrivate::ObjectInvoker::invoke(Argument) [with Derived = QtPrivate::QVariantValueHelper; Argument = const QVariant&; ReturnType = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:810:64: required from 'T qvariant_cast(const QVariant&) [with T = ISPSItem*]' ..........\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:348:36: required from 'T QVariant::value() const [with T = ISPSItem*]' ..\marssies\ispswidget.cpp:785:109: required from here EDIT3: I left those 2 lines commented and kept migrating the application, until I got the same error in another file, this is the line:
Im getting the same error in another .cpp using a different class, but what they have in common is the .value<Type>();
Notify* _n = ui.notifyBox->model()->data(index, Qt::UserRole).value<Notify*>();
So definitely its the .value<Type>();
what throws the error, now the only thing left is to find a way around it.
Here is the object ISPSItem in case its useful:
class ISPSItem : public QObject {
public:
enum Level {ROOT_LEVEL = 1,
ISPS_LEVEL,
GRAPHICS_LEVEL
} level;
ISPSItem(ISPSItem* = NULL, Level = ROOT_LEVEL, int = -1);
~ISPSItem();
ISPSItem* parentItem() {return _parentItem;}
ISPSItem* child(int);
void appendChild(ISPSItem*);
void insertChild(ISPSItem*, int);
int childCount() const {return children.size();}
int row() const;
int newNodeRow(Level);
void remove();
private:
QList<ISPSItem*> children;
ISPSItem* _parentItem;
void remove(ISPSItem*);
};
Q_DECLARE_METATYPE(ISPSItem*)
Upvotes: 2
Views: 8577
Reputation: 66
Add this before you use ISPSItem as a QVariant cast:
Q_DECLARE_METATYPE(ISPSItem)
To solve the problem you need to add your class to QMetaType, the macro do that.
Q_DECLARE_METATYPE(Type)
This macro makes the type Type known to QMetaType as long as it provides a public default constructor, a public copy constructor and a public destructor. It is needed to use the type Type as a custom type in QVariant.
Good look!
Upvotes: 3
Reputation: 95
I see this problem when I change signals variable type but at the same time I forgot changing slots descriptions.For example; I have a signal slot : this is signal-> setResult(bool res); this is slot -> setResult(bool res){}
I change signal's type signal -> setResult(QString res); slot -> setResult(bool res); /////WHEN I FORGOT CHANGING THIS ASSERT THIS EXP
Upvotes: 2
Reputation: 21240
After getting much information about the error and the sources that trigger it I conclude, that the root cause could be in using QObject
subclasses in QVariant, especially when calling QVariant::value()
function. As Qt docs say:
If the QVariant contains a pointer to a type derived from QObject then T may be any QObject type. If the pointer stored in the QVariant can be qobject_cast to T, then that result is returned. Otherwise a null pointer is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro.
I believe, that adding Q_OBJECT
macro to these classes (ISPSItem
) declaration will solve the problem.
Upvotes: 7