Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-116012

moc doesn't generate correct signal definition while using both macro and include file.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.7, 6.4.2
    • Build tools: moc
    • None
    • Linux/Wayland, Windows

    Description

      If you use an include file and macro for auto generating signals, moc may create incorrect signal definitions and cause compiling errors.

      Sample code:

       

      // 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 file "property_list" is:

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

      We'll get following compile 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);
            |          ^~~~ 

      If we change the signal sector, replace the #include directive with content of file "property_list", this issue will disappear. It looks like moc ran into some problem and generates incorrect code if we're using both macro & include file.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            fabiankosmale Fabian Kosmale
            farta Li Xiang
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes