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. GCC 16 warnings about incomplete types in an SFINAE context
Qt 6.11 is out! See what's new in the release blog

GCC 16 warnings about incomplete types in an SFINAE context

Scheduled Pinned Locked Moved Unsolved General and Desktop
24 Posts 6 Posters 2.5k Views 4 Watching
  • 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.
  • l3u_L Offline
    l3u_L Offline
    l3u_
    wrote last edited by
    #1

    Hi all,

    On my main desktop (Gentoo Linux) with GCC 15.2.1 and Clang 21.1.8, my projects build without any warning. Here, I have Qt 6.10.3.

    However, using GCC 16.1.1 and Qt 6.11.0 on my Artix machine, I get warnings like

    [30/203] Building CXX object CMakeFiles/muckturnier.dir/muckturnier_autogen/mocs_compilation.cpp.o
    In file included from /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/LPBBI7GBC7/moc_BoogerSpinBox.cpp:9,
                     from /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/mocs_compilation.cpp:82:
    /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/LPBBI7GBC7/../../../src/ScorePage/BoogerSpinBox.h:11:7: warning: defining ‘BoogerSpinBox’, which previously failed to be complete in a SFINAE context [-Wsfinae-incomplete=]
       11 | class BoogerSpinBox : public QSpinBox
          |       ^~~~~~~~~~~~~
    In file included from /usr/include/qt6/QtCore/qobject.h:18,
                     from /usr/include/qt6/QtWidgets/qwidget.h:10,
                     from /usr/include/qt6/QtWidgets/qdialog.h:9,
                     from /usr/include/qt6/QtWidgets/QDialog:1,
                     from /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/UVLADIE3JM/../../../src/shared/TitleDialog.h:9,
                     from /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/UVLADIE3JM/../../../src/AboutDialog.h:9,
                     from /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/UVLADIE3JM/moc_AboutDialog.cpp:9,
                     from /home/tobias/tmp/git/muckturnier/build/muckturnier_autogen/mocs_compilation.cpp:2:
    /usr/include/qt6/QtCore/qmetatype.h:343:64: note: here.  Use ‘-Wsfinae-incomplete=2’ for a diagnostic at that point
      343 |         static auto check(U *) -> std::integral_constant<bool, sizeof(U) != 0>;
          |                                                                ^~~~~~~~~
    

    From what I could find, this is something originating from Qt's meta object system, inside moc generated files.

    I have no idea why, in the example above, this happens with this very class (it's not different from other subclassed classes, and I use quite a lot) or what exactly triggers this.

    So: Is this something I should worry about? Can I do something about it? Setting -Wsfinae-incomplete=2 does, in contrast to what the warning says, not yield any additional information.

    Thanks for all insights!

    Cheers, Tobias

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote last edited by
      #2

      Hi,

      Did you consider including the moc files in the implementation ?

      KDAB has an excellent article/video about it.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • l3u_L Offline
        l3u_L Offline
        l3u_
        wrote last edited by
        #3

        Adding

        #include "moc_BoogerSpinBox.cpp"
        

        to the implementation does indeed silence the warning. But why does this happen in the first place? And why does this happen with this very class?! This is a very small class doing nothing special:

        Here's the header:

        #include <QSpinBox>
        
        class BoogerSpinBox : public QSpinBox
        {
            Q_OBJECT
        
        public:
            explicit BoogerSpinBox(QWidget *parent = nullptr);
            void deselect();
        
        Q_SIGNALS:
            void returnPressed();
            void scorePopupRequested(BoogerSpinBox *spinBox);
        
        protected:
            void contextMenuEvent(QContextMenuEvent *) override;
            void focusInEvent(QFocusEvent *event) override;
        
        };
        

        and here's the implementation:

        #include "BoogerSpinBox.h"
        #include <QDebug>
        #include <QLineEdit>
        #include <QFocusEvent>
        #include <QTimer>
        
        BoogerSpinBox::BoogerSpinBox(QWidget *parent) : QSpinBox(parent)
        {
            setWrapping(true);
            connect(lineEdit(), &QLineEdit::returnPressed, this, &BoogerSpinBox::returnPressed);
        }
        
        void BoogerSpinBox::contextMenuEvent(QContextMenuEvent *)
        {
            Q_EMIT scorePopupRequested(this);
        }
        
        void BoogerSpinBox::focusInEvent(QFocusEvent *event)
        {
            QSpinBox::focusInEvent(event);
            if (event->reason() == Qt::MouseFocusReason || event->reason() == Qt::TabFocusReason) {
                QTimer::singleShot(0, this, &QSpinBox::selectAll);
            }
        }
        
        void BoogerSpinBox::deselect()
        {
            lineEdit()->deselect();
        }
        

        … and that's it …

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote last edited by
          #4

          I wonder if it's because of scorePopupRequested

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • l3u_L Offline
            l3u_L Offline
            l3u_
            wrote last edited by
            #5

            Because the signal includes a pointer to the class itself?

            1 Reply Last reply
            0
            • Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote last edited by
              #6

              Just try it out by removing the signal. If this is the case then create a bug report with a mre.
              Don't know why you need yourself in a signal at all. This somehow looks quirky.

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

              1 Reply Last reply
              0
              • l3u_L Offline
                l3u_L Offline
                l3u_
                wrote last edited by
                #7

                Well, strictly speaking, you're absolutely right about the signal passing the object itself – this is quite old code I wrote years ago, when I didn't knew much about all the fancy not-so-new-anymore C++ features. Very likely, one could modernize this and use an std::bind connect passing the object. Maybe, I should review this. Thanks a lot for this hint – I was so busy wondering about what happens here that I didn't question the implementation itself!

                However, I'll try to track it down, and maybe, I can actually file a bug.

                Thanks again for the input :-)

                1 Reply Last reply
                0
                • l3u_L Offline
                  l3u_L Offline
                  l3u_
                  wrote last edited by
                  #8

                  It actually wasn't about the scorePopupRequested signal – but about another signal emitted from another class, but also referencing the BoogerSpinBox class. I removed the pointer to the respective object from both signals and used a std::bind connect instead. Now, the warning is gone.

                  I'm not sure if this is actually a bug, because if one implements it the way it's meant to be implemented, there's no problem. So I think this was a weird edge-case combination of old code and new GCC.

                  Thanks a lot for the help to track this down!

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote last edited by
                    #9

                    std::bind? Use lambda :)

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

                    1 Reply Last reply
                    1
                    • l3u_L Offline
                      l3u_L Offline
                      l3u_
                      wrote last edited by
                      #10

                      Yeah, that would of course work as well. But as long as nothing changes – in this case, I'm only passing a pointer to a function call, always the same one – I think std::bind is more elegant? Or is there (meanwhile) a reason not to do something like (staying with the above example)

                      connect(spinBox, &BoogerSpinBox::scorePopupRequested,
                              this, std::bind(&BoogerWidget::scorePopupRequested, this, spinBox));
                      

                      ?

                      JonBJ 1 Reply Last reply
                      0
                      • l3u_L l3u_

                        Yeah, that would of course work as well. But as long as nothing changes – in this case, I'm only passing a pointer to a function call, always the same one – I think std::bind is more elegant? Or is there (meanwhile) a reason not to do something like (staying with the above example)

                        connect(spinBox, &BoogerSpinBox::scorePopupRequested,
                                this, std::bind(&BoogerWidget::scorePopupRequested, this, spinBox));
                        

                        ?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote last edited by JonB
                        #11

                        @l3u_
                        We would write:

                        connect(spinBox, &BoogerSpinBox::scorePopupRequested,
                                this, [this, spinBox]() { this->onScorePopupRequested(spinBox); } );
                        

                        (The this-> just for clarity.) I don't know why you find std::bind() more "elegant" than this. You can also be more flexible on what you write in the lambda body than with a std::bind(), and may not even need an actual slot method at all. At any rate, you will see many examples using lambda-connect()s in Qt code.

                        1 Reply Last reply
                        0
                        • l3u_L Offline
                          l3u_L Offline
                          l3u_
                          wrote last edited by
                          #12

                          I actually do use lamdba connects in many places … well, maybe, it's a question of style and taste then.

                          However, I have to admit that the lambda version is a bit more clear about what's happening. Also, I'll never memorize that std::bind connect syntax, I have to look at another piece of my code each and every time I write one ;-)

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote last edited by
                            #13

                            Out of curiosity, do you even then that signal in the first place ?
                            Can you explain what happens in the slot connected to it ?

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • l3u_L Offline
                              l3u_L Offline
                              l3u_
                              wrote last edited by
                              #14

                              It's a quite simple use-case. I have a spinbox, whose value can also be set via a popup dialog. And the popup can be requested both through the context menu requested by the spinbox itself and through a radio button enabling the spinbox in the first place. Thus, the pointer to the spinbox that has to be updated is needed in the slot causing said popup to be shown, so that it's clear which spinbox's value has to be updated (there can be multiple ones).

                              Back in the day, I solved this by passing "this" in the signal emitted from the spinbox itself, or the respective pointer passed to the radio button enabling it – cf. the code above.

                              The original code has been written in "Effective Modern C++" C++11 times, so I sticked to std::bind when fixing the initial problem posted here. However, I now learned that std::bind was only needed when lambda connects weren't possible at all or not still reliable – but they are now. So there's no need to still use std::bind in this case.

                              1 Reply Last reply
                              0
                              • Christian EhrlicherC Offline
                                Christian EhrlicherC Offline
                                Christian Ehrlicher
                                Lifetime Qt Champion
                                wrote last edited by
                                #15

                                https://doc.qt.io/qt-6/qobject.html#sender

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

                                1 Reply Last reply
                                0
                                • l3u_L Offline
                                  l3u_L Offline
                                  l3u_
                                  wrote last edited by l3u_
                                  #16

                                  Yeah, I know this – and I also read the big fat warnings saying "This function violates the object-oriented principle of modularity" ;-)

                                  Also, I don't always need the sender, because the popup can be requested from a spinbox and from a radio button – but I always need the spinbox. So this couldn't even be used in this case.

                                  SGaistS 1 Reply Last reply
                                  0
                                  • l3u_L l3u_

                                    Yeah, I know this – and I also read the big fat warnings saying "This function violates the object-oriented principle of modularity" ;-)

                                    Also, I don't always need the sender, because the popup can be requested from a spinbox and from a radio button – but I always need the spinbox. So this couldn't even be used in this case.

                                    SGaistS Offline
                                    SGaistS Offline
                                    SGaist
                                    Lifetime Qt Champion
                                    wrote last edited by
                                    #17

                                    @l3u_ said in GCC 16 warnings about incomplete types in an SFINAE context:

                                    Yeah, I know this – and I also read the big fat warnings saying "This function violates the object-oriented principle of modularity" ;-)

                                    Also, I don't always need the sender, because the popup can be requested from a spinbox and from a radio button – but I always need the spinbox. So this couldn't even be used in this case.

                                    Technically, you're doing the same violation since your dialog has to know which object has called it.

                                    Usually, to keep things separated, it boils down to these two options:

                                    • Call the dialog in a fashion where you get back the value you want and set it to whatever control makes sense (e.g. QInputDialog)
                                    • Connect the dialog to the widget through signals and slots

                                    If you are reusing the dialog, nothing forbids you to disconnect and reconnect your widgets again and again.

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    1 Reply Last reply
                                    0
                                    • P Offline
                                      P Offline
                                      Plastic.Jesus
                                      wrote last edited by
                                      #18

                                      This bit my whole organization after we upgraded to Fedora 44 last week and got GCC 16 along for the ride.
                                      Every single TU where we were forward declaring any class involved in a signal or slot declaration (rather than including the header directly) generates this warning. Since we run -Wall and -Werror as policy it basically borked our entire code base.

                                      IMO this is really a Qt issue since the SFINAE-on-potentially-incomplete-type trait check is in moc's autogenerated output
                                      and QtPrivate::QMetaTypeForType::check() as opposed to user code.
                                      Qt's documentation has long encouraged forward-declaration in QObject headers for compile-time hygiene (rightly so!) That guidance is now actively unsafe under any -Werror build on GCC 14+.

                                      Now I'm left with a choice. I either suppress the warning (which I absolutely hate), or I include the headers and take the coimpile time hit on a project with 250,000 lines of code.

                                      It would be great if this could get fixed in the moc generation.

                                      JonBJ 1 Reply Last reply
                                      1
                                      • P Plastic.Jesus

                                        This bit my whole organization after we upgraded to Fedora 44 last week and got GCC 16 along for the ride.
                                        Every single TU where we were forward declaring any class involved in a signal or slot declaration (rather than including the header directly) generates this warning. Since we run -Wall and -Werror as policy it basically borked our entire code base.

                                        IMO this is really a Qt issue since the SFINAE-on-potentially-incomplete-type trait check is in moc's autogenerated output
                                        and QtPrivate::QMetaTypeForType::check() as opposed to user code.
                                        Qt's documentation has long encouraged forward-declaration in QObject headers for compile-time hygiene (rightly so!) That guidance is now actively unsafe under any -Werror build on GCC 14+.

                                        Now I'm left with a choice. I either suppress the warning (which I absolutely hate), or I include the headers and take the coimpile time hit on a project with 250,000 lines of code.

                                        It would be great if this could get fixed in the moc generation.

                                        JonBJ Offline
                                        JonBJ Offline
                                        JonB
                                        wrote last edited by
                                        #19

                                        @Plastic.Jesus said in GCC 16 warnings about incomplete types in an SFINAE context:

                                        It would be great if this could get fixed in the moc generation.

                                        I am not affected by this issue, but understand what you are saying. But if you wish or hope for some change in moc generation you would need to open an issue at https://qt-project.atlassian.net/issues/

                                        1 Reply Last reply
                                        0
                                        • P Offline
                                          P Offline
                                          Plastic.Jesus
                                          wrote last edited by
                                          #20

                                          @JonB understood. Just trying to get my arms fully wrapped around the implications.

                                          It turned out the compile-time hit was not as bad as I'd anticipated ~1-2% increase.

                                          I think the biggest impact in the real world is going to be the ambiguity of the compile warnings (or errors if -Werror). The GCC output is only for the .moc and there is really no indication of any kind as to the actual offending header, as I believe is the genesis of this topic. The OP is digging around trying to figure out what's wrong with his class, but the actual issue is in some other QObject which uses the class in a signal or slot declaration.

                                          Once I mess around with this a little more it'll probably be worth filing a ticket.

                                          Thanks!

                                          SGaistS 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