Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Auto-generated properties by macros failed due to using an included definition file.
QtWS25 Last Chance

Auto-generated properties by macros failed due to using an included definition file.

Scheduled Pinned Locked Moved Unsolved General and Desktop
signalpropertiesincludemacro
9 Posts 2 Posters 724 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.
  • F Offline
    F Offline
    farta
    wrote on last edited by
    #1

    Hello guys, I'm composing a Qt class with many qt properties. So, I want to use macros to reduce repeating work. My code looks like this:

    // myservice.h
    // the myservice.cpp is trivial, nothing more than an auto-generated constructor.
    #ifndef MYSERVICE_H
    #define MYSERVICE_H
    
    #include <QObject>
    
    class MyService : public QObject
    {
        Q_OBJECT
    public:
        explicit MyService(QObject *parent = nullptr);
    
    #define MY_PROPERTY(type, name) \
        Q_PROPERTY(type name MEMBER m_##name NOTIFY name##Changed)
    #include "property_list"
    #undef MY_PROPERTY
    
    signals:
    #define MY_PROPERTY(type, name) \
        void name##Changed(type);
    #include "property_list"
    #undef MY_PROPERTY
    
    private:
    #define MY_PROPERTY(type, name) \
        type m_##name;
    #include "property_list"
    #undef MY_PROPERTY
    };
    #endif // MYSERVICE_H
    

    And I'm using a property_list file to define properties, it looks like this:

    MY_PROPERTY(QString, value1)
    MY_PROPERTY(QString, value2)
    

    But during building, I got these errors:

    moc_myservice.cpp: In static member function ‘static void MyService::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)’:
    moc_myservice.cpp:92:41: error: no matching function for call to ‘MyService::value1Changed()’
       92 |                 Q_EMIT _t->value1Changed();
          |                        ~~~~~~~~~~~~~~~~~^~
    In file included from moc_myservice.cpp:10:
    ../qt01/property_list:1:22: note: candidate: ‘void MyService::value1Changed(QString)’
        1 | MY_PROPERTY(QString, value1)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    ../qt01/property_list:1:22: note:   candidate expects 1 argument, 0 provided
        1 | MY_PROPERTY(QString, value1)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    moc_myservice.cpp:98:41: error: no matching function for call to ‘MyService::value2Changed()’
       98 |                 Q_EMIT _t->value2Changed();
          |                        ~~~~~~~~~~~~~~~~~^~
    ../qt01/property_list:2:22: note: candidate: ‘void MyService::value2Changed(QString)’
        2 | MY_PROPERTY(QString, value2)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    ../qt01/property_list:2:22: note:   candidate expects 1 argument, 0 provided
        2 | MY_PROPERTY(QString, value2)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    moc_myservice.cpp: In function ‘void checkNotifySignalValidity_MyService(MyService*)’:
    moc_myservice.cpp:164:21: error: no matching function for call to ‘MyService::value1Changed()’
      164 |     t->value1Changed();
          |     ~~~~~~~~~~~~~~~~^~
    ../qt01/property_list:1:22: note: candidate: ‘void MyService::value1Changed(QString)’
        1 | MY_PROPERTY(QString, value1)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    ../qt01/property_list:1:22: note:   candidate expects 1 argument, 0 provided
        1 | MY_PROPERTY(QString, value1)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    moc_myservice.cpp:165:21: error: no matching function for call to ‘MyService::value2Changed()’
      165 |     t->value2Changed();
          |     ~~~~~~~~~~~~~~~~^~
    ../qt01/property_list:2:22: note: candidate: ‘void MyService::value2Changed(QString)’
        2 | MY_PROPERTY(QString, value2)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    ../qt01/property_list:2:22: note:   candidate expects 1 argument, 0 provided
        2 | MY_PROPERTY(QString, value2)
          |                      ^~~~~~
    ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
       19 |     void name##Changed(type);
          |          ^~~~
    

    It looks like Qt doesn't generate correct signal definitions. And I found that if I don't use a #include directive on signal macros, but paste property_list file's content like this:

    signals:
    #define MY_PROPERTY(type, name) \
        void name##Changed(type);
    MY_PROPERTY(QString, value1)
    MY_PROPERTY(QString, value2)
    #undef MY_PROPERTY
    

    All errors will then disappear.
    I've tried both Windows & Linux. Windows's compiler version is gcc 7.3 and linux's version is gcc 12.2. They both do the same thing.
    So here is the problem:

    1. Why a #include directive differs to pasting the content of the included file here?
    2. Is there a way to resolve this problem except pasting the file's content?

    Thanks a lot for any help.

    Christian EhrlicherC 1 Reply Last reply
    0
    • F farta

      Hello guys, I'm composing a Qt class with many qt properties. So, I want to use macros to reduce repeating work. My code looks like this:

      // myservice.h
      // the myservice.cpp is trivial, nothing more than an auto-generated constructor.
      #ifndef MYSERVICE_H
      #define MYSERVICE_H
      
      #include <QObject>
      
      class MyService : public QObject
      {
          Q_OBJECT
      public:
          explicit MyService(QObject *parent = nullptr);
      
      #define MY_PROPERTY(type, name) \
          Q_PROPERTY(type name MEMBER m_##name NOTIFY name##Changed)
      #include "property_list"
      #undef MY_PROPERTY
      
      signals:
      #define MY_PROPERTY(type, name) \
          void name##Changed(type);
      #include "property_list"
      #undef MY_PROPERTY
      
      private:
      #define MY_PROPERTY(type, name) \
          type m_##name;
      #include "property_list"
      #undef MY_PROPERTY
      };
      #endif // MYSERVICE_H
      

      And I'm using a property_list file to define properties, it looks like this:

      MY_PROPERTY(QString, value1)
      MY_PROPERTY(QString, value2)
      

      But during building, I got these errors:

      moc_myservice.cpp: In static member function ‘static void MyService::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)’:
      moc_myservice.cpp:92:41: error: no matching function for call to ‘MyService::value1Changed()’
         92 |                 Q_EMIT _t->value1Changed();
            |                        ~~~~~~~~~~~~~~~~~^~
      In file included from moc_myservice.cpp:10:
      ../qt01/property_list:1:22: note: candidate: ‘void MyService::value1Changed(QString)’
          1 | MY_PROPERTY(QString, value1)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      ../qt01/property_list:1:22: note:   candidate expects 1 argument, 0 provided
          1 | MY_PROPERTY(QString, value1)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      moc_myservice.cpp:98:41: error: no matching function for call to ‘MyService::value2Changed()’
         98 |                 Q_EMIT _t->value2Changed();
            |                        ~~~~~~~~~~~~~~~~~^~
      ../qt01/property_list:2:22: note: candidate: ‘void MyService::value2Changed(QString)’
          2 | MY_PROPERTY(QString, value2)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      ../qt01/property_list:2:22: note:   candidate expects 1 argument, 0 provided
          2 | MY_PROPERTY(QString, value2)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      moc_myservice.cpp: In function ‘void checkNotifySignalValidity_MyService(MyService*)’:
      moc_myservice.cpp:164:21: error: no matching function for call to ‘MyService::value1Changed()’
        164 |     t->value1Changed();
            |     ~~~~~~~~~~~~~~~~^~
      ../qt01/property_list:1:22: note: candidate: ‘void MyService::value1Changed(QString)’
          1 | MY_PROPERTY(QString, value1)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      ../qt01/property_list:1:22: note:   candidate expects 1 argument, 0 provided
          1 | MY_PROPERTY(QString, value1)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      moc_myservice.cpp:165:21: error: no matching function for call to ‘MyService::value2Changed()’
        165 |     t->value2Changed();
            |     ~~~~~~~~~~~~~~~~^~
      ../qt01/property_list:2:22: note: candidate: ‘void MyService::value2Changed(QString)’
          2 | MY_PROPERTY(QString, value2)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      ../qt01/property_list:2:22: note:   candidate expects 1 argument, 0 provided
          2 | MY_PROPERTY(QString, value2)
            |                      ^~~~~~
      ../qt01/myservice.h:19:10: note: in definition of macro ‘MY_PROPERTY’
         19 |     void name##Changed(type);
            |          ^~~~
      

      It looks like Qt doesn't generate correct signal definitions. And I found that if I don't use a #include directive on signal macros, but paste property_list file's content like this:

      signals:
      #define MY_PROPERTY(type, name) \
          void name##Changed(type);
      MY_PROPERTY(QString, value1)
      MY_PROPERTY(QString, value2)
      #undef MY_PROPERTY
      

      All errors will then disappear.
      I've tried both Windows & Linux. Windows's compiler version is gcc 7.3 and linux's version is gcc 12.2. They both do the same thing.
      So here is the problem:

      1. Why a #include directive differs to pasting the content of the included file here?
      2. Is there a way to resolve this problem except pasting the file's content?

      Thanks a lot for any help.

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      It's not a compiler problem but the moc parser. This can only be fixed when someone enhance moc but I guess the usecase is to rare that someone is willing to do it.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      F 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        It's not a compiler problem but the moc parser. This can only be fixed when someone enhance moc but I guess the usecase is to rare that someone is willing to do it.

        F Offline
        F Offline
        farta
        wrote on last edited by
        #3

        @Christian-Ehrlicher Thanks a lot. I got this problem on qt5. I'll try qt6 and if it has the same problem I'll try to file a bug to make it known to qt dev team at least.

        Christian EhrlicherC 1 Reply Last reply
        0
        • F farta

          @Christian-Ehrlicher Thanks a lot. I got this problem on qt5. I'll try qt6 and if it has the same problem I'll try to file a bug to make it known to qt dev team at least.

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @farta it will not work with Qt6 either. You can create a bug report but this limitation is already known. There were attempts to use llvm for the parser but it was to slow.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          F 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @farta it will not work with Qt6 either. You can create a bug report but this limitation is already known. There were attempts to use llvm for the parser but it was to slow.

            F Offline
            F Offline
            farta
            wrote on last edited by
            #5

            @Christian-Ehrlicher lol if it is a known issue maybe it is not a good idea to report it again. Do you have the bug link at hand right now?

            Christian EhrlicherC 1 Reply Last reply
            0
            • F farta

              @Christian-Ehrlicher lol if it is a known issue maybe it is not a good idea to report it again. Do you have the bug link at hand right now?

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @farta you can create a bug report - should not hurt.
              Search for 'moc' and 'llvm' - maybe there is a task for it.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              F 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @farta you can create a bug report - should not hurt.
                Search for 'moc' and 'llvm' - maybe there is a task for it.

                F Offline
                F Offline
                farta
                wrote on last edited by
                #7

                @Christian-Ehrlicher OK my bug posted.

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

                Hope for the dev team it means sth.

                Christian EhrlicherC 1 Reply Last reply
                0
                • F farta

                  @Christian-Ehrlicher OK my bug posted.

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

                  Hope for the dev team it means sth.

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  You should attach a minimal, compilable example to the bug report.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  F 1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    You should attach a minimal, compilable example to the bug report.

                    F Offline
                    F Offline
                    farta
                    wrote on last edited by
                    #9

                    @Christian-Ehrlicher Thank you for your advice. The sample code has been added to the bug report.

                    1 Reply Last reply
                    1

                    • Login

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