Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Qt 6
  4. Strange MOC related error with Q_DECLARE_METATYPE()
Forum Updated to NodeBB v4.3 + New Features

Strange MOC related error with Q_DECLARE_METATYPE()

Scheduled Pinned Locked Moved Unsolved Qt 6
metatypemocqt6
4 Posts 2 Posters 1.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • oblivioncthO Offline
    oblivioncthO Offline
    oblivioncth
    wrote on last edited by oblivioncth
    #1

    I'm porting an application from Qt5 to Qt6 and ran into a bizarre issue.

    Minimal Example
    [CMakeLists.txt]

    cmake_minimum_required(VERSION 3.19)
    
    project(MetaTypeIssue VERSION 0.1 LANGUAGES CXX)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    set(CMAKE_AUTOMOC ON)
    
    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
    
    set(PROJECT_SOURCES
            main.cpp
            m.h
            foo.h
    )
    if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
        qt_add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
    else()
        add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
    endif()
    
    target_link_libraries(MetaTypeIssue PRIVATE Qt${QT_VERSION_MAJOR}::Core)
    

    [foo.h]

    #ifndef FOO_H
    #define FOO_H
    
    #include <QObject>
    
    class Foo : public QObject
    {
        Q_OBJECT
    
    public:
        Foo() {}
    
    signals:
    
        void sig(std::shared_ptr<int> var);
    };
    
    #endif // FOO_H
    

    [m.h]

    #ifndef BAR_H
    #define BAR_H
    
    #include <QObject>
    
    class Bar : public QObject
    {
        Q_OBJECT
    
    public:
        Bar() {}
    };
    Q_DECLARE_METATYPE(std::shared_ptr<int>);
    
    #endif // BAR_H
    

    [main.cpp]

    #include <QCoreApplication>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        return a.exec();
    }
    

    Trying to compile this setup with Qt 6 (6.2.4) results in:

    m.h:13: error: C2908: explicit specialization; 'QMetaTypeId<T>' has already been instantiated
    m.h:13: error: C2766: explicit specialization; 'QMetaTypeId<T>' has already been defined
    qmetatype.h:1132: see previous definition of 'QMetaTypeId<std::shared_ptr<int> >'
    

    Some changes that "prevent" the errors:

    • Change the parameter type of Foo::sig() to be different than that in Q_DECLARE_METATYPE() (obviously breaks functionality)
    • Disable auto-MOC (obviously causes linker errors)
    • Rename m.h to any name that doesn't start with an 'm'
    • Compile with Qt 5 (tested with 5.12.3)

    I was hoping to see if anyone could reproduce this or note if/why this outright shouldn't work if that really is the case for some reason.

    Here is the above MRE for convenience: https://www.mediafire.com/file/lm35jkzipj0hmwy/MetaTypeIssue.zip/file

    The original application was able to use shared_ptr<int> as a signal argument just fine, though it was only through a queued connection briefly before threading changes were made, but I'm pretty sure it worked the same when queued.

    EDIT: Corrected accidental usage of unique_ptr in example code instead of shared_ptr (what it actually was/is).

    M 1 Reply Last reply
    0
    • M Offline
      M Offline
      MB12
      wrote on last edited by MB12
      #2

      Hello, were you able to resolve this error?
      I am running into this issue when upgrading from QT5 to QT6. Any ideas on troubleshooting this would be appreciated.

      1 Reply Last reply
      0
      • oblivioncthO oblivioncth

        I'm porting an application from Qt5 to Qt6 and ran into a bizarre issue.

        Minimal Example
        [CMakeLists.txt]

        cmake_minimum_required(VERSION 3.19)
        
        project(MetaTypeIssue VERSION 0.1 LANGUAGES CXX)
        
        set(CMAKE_CXX_STANDARD 17)
        set(CMAKE_CXX_STANDARD_REQUIRED ON)
        
        set(CMAKE_AUTOMOC ON)
        
        find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
        find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
        
        set(PROJECT_SOURCES
                main.cpp
                m.h
                foo.h
        )
        if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
            qt_add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
        else()
            add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})
        endif()
        
        target_link_libraries(MetaTypeIssue PRIVATE Qt${QT_VERSION_MAJOR}::Core)
        

        [foo.h]

        #ifndef FOO_H
        #define FOO_H
        
        #include <QObject>
        
        class Foo : public QObject
        {
            Q_OBJECT
        
        public:
            Foo() {}
        
        signals:
        
            void sig(std::shared_ptr<int> var);
        };
        
        #endif // FOO_H
        

        [m.h]

        #ifndef BAR_H
        #define BAR_H
        
        #include <QObject>
        
        class Bar : public QObject
        {
            Q_OBJECT
        
        public:
            Bar() {}
        };
        Q_DECLARE_METATYPE(std::shared_ptr<int>);
        
        #endif // BAR_H
        

        [main.cpp]

        #include <QCoreApplication>
        
        int main(int argc, char *argv[])
        {
            QCoreApplication a(argc, argv);
            return a.exec();
        }
        

        Trying to compile this setup with Qt 6 (6.2.4) results in:

        m.h:13: error: C2908: explicit specialization; 'QMetaTypeId<T>' has already been instantiated
        m.h:13: error: C2766: explicit specialization; 'QMetaTypeId<T>' has already been defined
        qmetatype.h:1132: see previous definition of 'QMetaTypeId<std::shared_ptr<int> >'
        

        Some changes that "prevent" the errors:

        • Change the parameter type of Foo::sig() to be different than that in Q_DECLARE_METATYPE() (obviously breaks functionality)
        • Disable auto-MOC (obviously causes linker errors)
        • Rename m.h to any name that doesn't start with an 'm'
        • Compile with Qt 5 (tested with 5.12.3)

        I was hoping to see if anyone could reproduce this or note if/why this outright shouldn't work if that really is the case for some reason.

        Here is the above MRE for convenience: https://www.mediafire.com/file/lm35jkzipj0hmwy/MetaTypeIssue.zip/file

        The original application was able to use shared_ptr<int> as a signal argument just fine, though it was only through a queued connection briefly before threading changes were made, but I'm pretty sure it worked the same when queued.

        EDIT: Corrected accidental usage of unique_ptr in example code instead of shared_ptr (what it actually was/is).

        M Offline
        M Offline
        MB12
        wrote on last edited by
        #3

        @oblivioncth
        This is to confirm that I am able to reproduce the issue on QT 6.4.2 on MacOS.
        The project I am trying to port is much bigger and the filename that results in this error does not start with 'm'.

        [ 25%] Automatic MOC for target MetaTypeIssue
        [ 25%] Built target MetaTypeIssue_autogen
        [ 50%] Building CXX object CMakeFiles/MetaTypeIssue.dir/MetaTypeIssue_autogen/mocs_compilation.cpp.o
        In file included from /var/tmp/meta_issue/build/MetaTypeIssue_autogen/mocs_compilation.cpp:3:
        In file included from /var/tmp/meta_issue/build/MetaTypeIssue_autogen/EWIEGA46WW/moc_m.cpp:10:
        /var/tmp/meta_issue/build/MetaTypeIssue_autogen/EWIEGA46WW/../../../m.h:13:1: error: explicit specialization of 'QMetaTypeId<std::shared_ptr<int>>' after instantiation
        Q_DECLARE_METATYPE(std::shared_ptr<int>);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /opt/homebrew/include/QtCore/qmetatype.h:1399:34: note: expanded from macro 'Q_DECLARE_METATYPE'
        #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        /opt/homebrew/include/QtCore/qmetatype.h:1403:12: note: expanded from macro 'Q_DECLARE_METATYPE_IMPL'
        struct QMetaTypeId< TYPE >
        ^~~~~~~~~~~~~~~~~~~
        /opt/homebrew/include/QtCore/qmetatype.h:1122:22: note: implicit instantiation first required here
        enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
        ^
        1 error generated.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          MB12
          wrote on last edited by
          #4

          I have created a bug report regarding this. I used the minimal example that you have created in the bug report. Thanks for sharing your minimal example.

          https://bugreports.qt.io/browse/QTBUG-111968

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved