Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    Unsolved MOC: signals and slots can't be on same line

    General and Desktop
    moc qt5.15.2 linker errors
    4
    17
    342
    Loading More Posts
    • 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.
    • M
      mattfbacon last edited by mattfbacon

      See post #10, where the same-line issue was located.


      I have some macros to declare slots and signals:

      #define SIGNAL_SLOT(NAME, ...) \
        public slots: \
        void update_ ## NAME(__VA_ARGS__); \
        signals: \
        void NAME ## _changed(__VA_ARGS__)
      

      which I use like this:

      class Foo : public QObject {
        Q_OBJECT
      // ...
        SIGNAL_SLOT(property, bool);
      }
      

      Previously when using a similar set of macros that had to be placed inside a signals: or public slots: section created in the regular way, and thus not having signals: or public slots: inside the macro, it worked perfectly fine.

      However, now that I've combined them (more DRY), it doesn't seem to work as I get linking errors relating to the signals, specifically undefined reference to Foo::property_changed(bool).

      I have inspected moc -E's output to see if anything strange was going on, but moc expands the macros just fine. Is the issue that signals/slots can't be on the same line as the section labels? Because this works for other C++ section labels like public: or protected:...

      I read that this was an issue with Qt 4, but that Qt 5's moc does expand macros, which is reaffirmed by the output of moc -E.

      So what's the issue here?


      I've tried:

      • Not using __VA_ARGS__: nothing changed; moc -E had exact same output
      • Adding signals: verbatim within the class: nothing changed except the output of moc -E
      • Switching to gcc: same error message, just harder to read
      • Using Q_SLOTS and Q_SIGNALS inside the macro rather than slots and signals: interestingly, does change the output of moc -E which I did not expect (I thought the latters expanded to the formers), but same issue nonetheless

      Versions:

      • Qt 5.15.2 (matching versions for all utilities)
      • QMake 3.1
      • Clang 12.0.0
      • Arch Linux on kernel 5.12.14
      1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by

        Feel free to provide a patch to moc for your usecase :)

        Qt has to stay free or it will die.

        M 1 Reply Last reply Reply Quote 0
        • M
          mattfbacon @Christian Ehrlicher last edited by

          @Christian-Ehrlicher The issue I have is in regards to what specifically MOC is struggling with. moc -E shows the correct output.

          1 Reply Last reply Reply Quote 0
          • M
            mattfbacon last edited by

            If I can get confirmation that this is intended behavior, I will just revert to using 2 macros. I just want to make sure this isn't a bug.

            1 Reply Last reply Reply Quote 0
            • Christian Ehrlicher
              Christian Ehrlicher Lifetime Qt Champion last edited by

              As it does not work it's not implemented in moc so it's a not intended use case. If you want this feature provide a patch, maybe it gets integrated.

              Qt has to stay free or it will die.

              M 1 Reply Last reply Reply Quote 0
              • V
                VRonin last edited by

                did you try the inline versions?

                #define SIGNAL_SLOT(NAME, ...) \
                  Q_SLOT void update_ ## NAME(__VA_ARGS__); \
                  Q_SIGNAL void NAME ## _changed(__VA_ARGS__)
                

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                M 1 Reply Last reply Reply Quote 1
                • M
                  mattfbacon @Christian Ehrlicher last edited by

                  @Christian-Ehrlicher doesn't work != not implemented. As I said before I want to make sure it's not a bug. The same code written out without macros works fine, and the macros are all expanded correctly according to moc -E.

                  1 Reply Last reply Reply Quote 0
                  • Christian Ehrlicher
                    Christian Ehrlicher Lifetime Qt Champion last edited by

                    Please show a header which does not work, without any macros so we can see what you really want and what not work.

                    Qt has to stay free or it will die.

                    M 1 Reply Last reply Reply Quote 0
                    • M
                      mattfbacon @VRonin last edited by

                      @VRonin Yes this works!! Thank you for addressing the problem 😌 I guess I am still a bit of a Qt newbie, since I've never heard of those inline annotations, but they are super useful for macros like these!

                      1 Reply Last reply Reply Quote 0
                      • M
                        mattfbacon @Christian Ehrlicher last edited by mattfbacon

                        @Christian-Ehrlicher I believe I have found the underlying issue:

                        Expanding the macros to exactly their output:

                        class Foo : public QObject {
                          Q_OBJECT
                        // ...
                        public slots: void update_property(bool); signals: void property_changed(bool);
                        protected:
                          bool property;
                        };
                        

                        does not compile either (same linker errors with the signals). You can't have slots and signals on the same line. However, C++ is meant to be a whitespace-insensitive language, so I still think this is a bug in MOC, albeit a different one. I will change the title.

                        JKSH 1 Reply Last reply Reply Quote 0
                        • Christian Ehrlicher
                          Christian Ehrlicher Lifetime Qt Champion last edited by

                          Even it's a 'bug' in moc it will unlikely to be changed, and when then not before 6.3 so ... don't see why this is needed though.

                          Qt has to stay free or it will die.

                          M 1 Reply Last reply Reply Quote 0
                          • JKSH
                            JKSH Moderators @mattfbacon last edited by

                            @mattfbacon said in MOC: signals and slots can't be on same line:

                            C++ is meant to be a whitespace-insensitive language, so I still think this is a bug in MOC

                            Yes, C++ is meant to be whitespace-insensitive. However, moc currently parses files using a custom text processor, not a full-fledged C++ engine. The processor currently doesn't support having "signals:" and "slots:" on the same line.

                            If you're interested, here's an experiment that reimplements moc on top of libclang, which gives it more capabilities in understanding arbitrary C++: https://woboq.com/blog/moc-with-clang.html

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            M 1 Reply Last reply Reply Quote 3
                            • M
                              mattfbacon @JKSH last edited by

                              @JKSH Interesting. Looks like moc-ng is fully functional; I will have to try that on my project.

                              M 1 Reply Last reply Reply Quote 0
                              • M
                                mattfbacon @mattfbacon last edited by

                                @JKSH Scratch that, just realized that the project is almost two years old and won't compile. Really, moc should be using a full C++ parser...

                                JKSH Christian Ehrlicher 2 Replies Last reply Reply Quote 0
                                • M
                                  mattfbacon @Christian Ehrlicher last edited by

                                  @Christian-Ehrlicher It's not strictly needed but without it the signals: and slots: section labels don't work like others. This makes signals and slots a leaky abstraction. This is especially true when you consider that Qt 5 moc is supposed to support macros, but macros can't have newlines so they are forced to put it all on the same line. In this context, unless you want to mark everything inline with Q_SLOT and Q_SIGNAL (and $DEITY forbid your macro actually wants to change the context for code after it), you're out of luck.

                                  1 Reply Last reply Reply Quote 0
                                  • JKSH
                                    JKSH Moderators @mattfbacon last edited by

                                    @mattfbacon said in MOC: signals and slots can't be on same line:

                                    Really, moc should be using a full C++ parser...

                                    I agree, that would be ideal.

                                    However, something like libclang did not exist when moc was invented. To reimplement it now with libclang is a costly and risky exercise. Can you show that the benefits outweigh the risks?

                                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                    1 Reply Last reply Reply Quote 0
                                    • Christian Ehrlicher
                                      Christian Ehrlicher Lifetime Qt Champion @mattfbacon last edited by

                                      @mattfbacon said in MOC: signals and slots can't be on same line:

                                      Really, moc should be using a full C++ parser...

                                      Again: feel free to provide a patch instead blaming around that a corner case does not work...

                                      Qt has to stay free or it will die.

                                      1 Reply Last reply Reply Quote 0
                                      • First post
                                        Last post