2
votes

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*)
3
This is Qt code, but what is your code that produces this error?vahancho
Thats the thing, I have no idea which part of the code triggers this, and the compilator doesnt offer any info. Id try to find it but I didnt program it and there are 798 .cpps and .h's, its driving me crazy EDIT: I found all the files that include qglobal.h, but none of them use any kind of assert function.Victor
@vahancho Such an error ist not always traceble to your own code. Something includes something which includes something which includes qglobal.h. I have a similar problem which fortunately only results in a warning so i can ignore it but it also resides in qglobal.h and occured when i ported to Qt 5.2.1Bowdzone
Just out of curiosity....can you trace this down to a specific file being compiled and maybe undef __COUNTER__ on the top to see what happens? Maybe this define is new to 5.2.1 but also used for something completly different by something else in your or 3rd party code.Bowdzone
As vahancho wrote, please show more information about your code. For instance, show the whole compiler error output which gives some starting from your code.lpapp

3 Answers

7
votes

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.

2
votes

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

2
votes

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!