Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Qt6 C++ compilation changes

Qt6 C++ compilation changes

Scheduled Pinned Locked Moved Unsolved C++ Gurus
17 Posts 6 Posters 1.9k 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.
  • J Offline
    J Offline
    JonB
    wrote on 7 Sept 2024, 10:50 last edited by JonB 9 Jul 2024, 10:57
    #1

    I am moving existing code which compiles fine under Qt5.15, gcc 11.4.0, -std=gnu++1z (C++17) to Qt6, gcc 13.2.0, also -std=gnu++1z.

    I have a couple of errors in new Qt6 vs Qt5 compilation for which I would like to know the actual reason. I have a correction/workaround in each case but I should still like to understand what the difference is to improve my C++ knowledge. It happens that both of these relate to "implicit type conversion" rules which I clearly don't know fully.

    First qsizetype:

    std::max(function_returning_qsizetype(), 10)
    >> error: no matching function for call to ‘max(qsizetype, int)’
    

    I now have change to:

    std::max(function_returning_qsizetype(), 10LL)
    

    Why did 10 used to work but now requires 10LL? Note that

    qsizetype st{10} /* or st(10) */;
    std::max(function_returning_qsizetype(), st)
    

    works, so at some level we can assign 10 to a qsizetype.

    Second QFlags<...> to QVariant:
    Returning a value from QVariant QAbstractItemModel::data()

    case Qt::TextAlignmentRole:
        return Qt::AlignHCenter | Qt::AlignVCenter;
    >> could not convert ‘Qt::operator|(Qt::AlignHCenter, Qt::AlignVCenter)’ from ‘QFlags<Qt::AlignmentFlag>’ to ‘QVariant’
    

    Note that:

        QFlags<Qt::AlignmentFlag> fl(Qt::AlignHCenter | Qt::AlignVCenter);
        return fl;
    

    doesn't help, same error on return statement.

    I now have change to:

    return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
    

    Why do I now need to cast/construct explicitly? Also why does

    return Qt::AlignCenter;
    

    work OK (without QVariant(...)) given the definition is

    enum AlignmentFlag {
    ...
    AlignCenter = AlignVCenter | AlignHCenter
    };
    Q_DECLARE_FLAGS(Alignment, AlignmentFlag)
    
    S 1 Reply Last reply 11 Sept 2024, 06:26
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 9 Sept 2024, 15:49 last edited by
      #2

      Wrt std::max():

      std::max() is a template :

      template< class T >
      const T& max( const T& a, const T& b );
      

      As you can see both a and b must be of the same type. 10 is an int32_t by design. qsizetype is std::ssize_t which is 64 bit on 64bit platforms. So the real question here is - why did it work with Qt5. Did you use 32 bit there?

      Wrt to QFlags:

      I would guess there was an implicit conversion to uint in Qt5 for QFlags<T> which was removed. Maybe now QT_TYPESAFE_FLAGS is defined by default to avoid this conversion.

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

      J 1 Reply Last reply 9 Sept 2024, 16:06
      2
      • C Christian Ehrlicher
        9 Sept 2024, 15:49

        Wrt std::max():

        std::max() is a template :

        template< class T >
        const T& max( const T& a, const T& b );
        

        As you can see both a and b must be of the same type. 10 is an int32_t by design. qsizetype is std::ssize_t which is 64 bit on 64bit platforms. So the real question here is - why did it work with Qt5. Did you use 32 bit there?

        Wrt to QFlags:

        I would guess there was an implicit conversion to uint in Qt5 for QFlags<T> which was removed. Maybe now QT_TYPESAFE_FLAGS is defined by default to avoid this conversion.

        J Offline
        J Offline
        JonB
        wrote on 9 Sept 2024, 16:06 last edited by JonB 9 Sept 2024, 16:08
        #3

        @Christian-Ehrlicher

        why did it work with Qt5. Did you use 32 bit there?

        Absolutely not, 64-bit.

        Was qsizetype defined as std::ssize_t at Qt5, did it change subtly at Qt6?

        If not, gcc version has been upped (per my initial post) at my new Ubuntu 24.04, it might be that?

        I still don't totally understand that e.g. ints (like an unqualified literal number) match longs but seemingly not long longs.

        It's a pain to have to change literals like 10 to 10LL to use std::max(). Most Qt classes with count()/size() (like QList) return qsizetype/long long and will require this of me now/for existing code.

        C 1 Reply Last reply 9 Sept 2024, 16:08
        0
        • J JonB
          9 Sept 2024, 16:06

          @Christian-Ehrlicher

          why did it work with Qt5. Did you use 32 bit there?

          Absolutely not, 64-bit.

          Was qsizetype defined as std::ssize_t at Qt5, did it change subtly at Qt6?

          If not, gcc version has been upped (per my initial post) at my new Ubuntu 24.04, it might be that?

          I still don't totally understand that e.g. ints (like an unqualified literal number) match longs but seemingly not long longs.

          It's a pain to have to change literals like 10 to 10LL to use std::max(). Most Qt classes with count()/size() (like QList) return qsizetype/long long and will require this of me now/for existing code.

          C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 9 Sept 2024, 16:08 last edited by
          #4

          @JonB said in Qt6 C++ compilation changes:

          Was qsizetype defined as std::ssize_t at Qt5, did it change subtly at Qt6?

          No, see the docs: https://doc.qt.io/qt-5/qtglobal.html#qsizetype-alias

          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
          • S Offline
            S Offline
            sierdzio
            Moderators
            wrote on 10 Sept 2024, 04:51 last edited by
            #5

            qsizetype is used for container indexing and that DID change in Qt 6. In Qt 5 containers returned size() as int (so 32 bit on most platforms).

            But if your function really retuned qsizetype in Qt 5 then I'm not entirely sure what's the deal.

            (Z(:^

            J 1 Reply Last reply 10 Sept 2024, 10:00
            1
            • S sierdzio
              10 Sept 2024, 04:51

              qsizetype is used for container indexing and that DID change in Qt 6. In Qt 5 containers returned size() as int (so 32 bit on most platforms).

              But if your function really retuned qsizetype in Qt 5 then I'm not entirely sure what's the deal.

              J Offline
              J Offline
              JonB
              wrote on 10 Sept 2024, 10:00 last edited by JonB 9 Oct 2024, 10:13
              #6

              @sierdzio
              Thanks, this sparked me to investigate. I happened to be using QJsonArray::count() as the function being passed to std::max(jsonArray.count(), 10).

              • https://doc.qt.io/qt-5/qjsonarray.html#count: int QJsonArray::count() const
              • https://doc.qt.io/qt-6/qjsonarray.html#count: qsizetype QJsonArray::count() const

              So at Qt6 it changed from int to qsizetype. This also answers @Christian-Ehrlicher as to why (without me being 32-bit). Hence the error at Qt6 but not at Qt5.....

              Now then. This change has been made throughout Qt6, e.g. QList::count() has moved from int to qsizetype similarly. That means potentially I will have a number of similar issues as & when I move other code from Qt5 to Qt6.... :(

              [BTW: Searching for changes from Qt5 to Qt6. I have no trouble finding lists of new or removed functions. I am unable to find where changes are documented for existing functions, such as this change in return types? Anywhere.]

              E J 2 Replies Last reply 10 Sept 2024, 15:31
              0
              • J JonB
                10 Sept 2024, 10:00

                @sierdzio
                Thanks, this sparked me to investigate. I happened to be using QJsonArray::count() as the function being passed to std::max(jsonArray.count(), 10).

                • https://doc.qt.io/qt-5/qjsonarray.html#count: int QJsonArray::count() const
                • https://doc.qt.io/qt-6/qjsonarray.html#count: qsizetype QJsonArray::count() const

                So at Qt6 it changed from int to qsizetype. This also answers @Christian-Ehrlicher as to why (without me being 32-bit). Hence the error at Qt6 but not at Qt5.....

                Now then. This change has been made throughout Qt6, e.g. QList::count() has moved from int to qsizetype similarly. That means potentially I will have a number of similar issues as & when I move other code from Qt5 to Qt6.... :(

                [BTW: Searching for changes from Qt5 to Qt6. I have no trouble finding lists of new or removed functions. I am unable to find where changes are documented for existing functions, such as this change in return types? Anywhere.]

                E Offline
                E Offline
                ekkescorner
                Qt Champions 2016
                wrote on 10 Sept 2024, 15:31 last edited by
                #7

                @JonB said in Qt6 C++ compilation changes:

                Searching for changes from Qt5 to Qt6

                here's my checklist what I found out while porting (mobile) apps from 5.15 to 6.7:
                https://t1p.de/ekkeChecklist

                ekke ... Qt Champion 2016 | 2024 ... mobile business apps
                5.15 --> 6.8 https://t1p.de/ekkeChecklist
                QMake --> CMake https://t1p.de/ekkeCMakeMobileApps

                1 Reply Last reply
                5
                • J JonB
                  10 Sept 2024, 10:00

                  @sierdzio
                  Thanks, this sparked me to investigate. I happened to be using QJsonArray::count() as the function being passed to std::max(jsonArray.count(), 10).

                  • https://doc.qt.io/qt-5/qjsonarray.html#count: int QJsonArray::count() const
                  • https://doc.qt.io/qt-6/qjsonarray.html#count: qsizetype QJsonArray::count() const

                  So at Qt6 it changed from int to qsizetype. This also answers @Christian-Ehrlicher as to why (without me being 32-bit). Hence the error at Qt6 but not at Qt5.....

                  Now then. This change has been made throughout Qt6, e.g. QList::count() has moved from int to qsizetype similarly. That means potentially I will have a number of similar issues as & when I move other code from Qt5 to Qt6.... :(

                  [BTW: Searching for changes from Qt5 to Qt6. I have no trouble finding lists of new or removed functions. I am unable to find where changes are documented for existing functions, such as this change in return types? Anywhere.]

                  J Offline
                  J Offline
                  JoeCFD
                  wrote on 10 Sept 2024, 19:42 last edited by JoeCFD 9 Oct 2024, 19:45
                  #8

                  @JonB Here QVector, QList?

                  QList's (and hence QVector's) size type is changed from int to qsizetype. Together with the size type, all relevant methods' signatures are updated to use qsizetype. This allows QList to hold more than 2^31 items on 64 bit platforms.

                  1 Reply Last reply
                  1
                  • J JonB
                    7 Sept 2024, 10:50

                    I am moving existing code which compiles fine under Qt5.15, gcc 11.4.0, -std=gnu++1z (C++17) to Qt6, gcc 13.2.0, also -std=gnu++1z.

                    I have a couple of errors in new Qt6 vs Qt5 compilation for which I would like to know the actual reason. I have a correction/workaround in each case but I should still like to understand what the difference is to improve my C++ knowledge. It happens that both of these relate to "implicit type conversion" rules which I clearly don't know fully.

                    First qsizetype:

                    std::max(function_returning_qsizetype(), 10)
                    >> error: no matching function for call to ‘max(qsizetype, int)’
                    

                    I now have change to:

                    std::max(function_returning_qsizetype(), 10LL)
                    

                    Why did 10 used to work but now requires 10LL? Note that

                    qsizetype st{10} /* or st(10) */;
                    std::max(function_returning_qsizetype(), st)
                    

                    works, so at some level we can assign 10 to a qsizetype.

                    Second QFlags<...> to QVariant:
                    Returning a value from QVariant QAbstractItemModel::data()

                    case Qt::TextAlignmentRole:
                        return Qt::AlignHCenter | Qt::AlignVCenter;
                    >> could not convert ‘Qt::operator|(Qt::AlignHCenter, Qt::AlignVCenter)’ from ‘QFlags<Qt::AlignmentFlag>’ to ‘QVariant’
                    

                    Note that:

                        QFlags<Qt::AlignmentFlag> fl(Qt::AlignHCenter | Qt::AlignVCenter);
                        return fl;
                    

                    doesn't help, same error on return statement.

                    I now have change to:

                    return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
                    

                    Why do I now need to cast/construct explicitly? Also why does

                    return Qt::AlignCenter;
                    

                    work OK (without QVariant(...)) given the definition is

                    enum AlignmentFlag {
                    ...
                    AlignCenter = AlignVCenter | AlignHCenter
                    };
                    Q_DECLARE_FLAGS(Alignment, AlignmentFlag)
                    
                    S Offline
                    S Offline
                    SimonSchroeder
                    wrote on 11 Sept 2024, 06:26 last edited by
                    #9

                    @JonB said in Qt6 C++ compilation changes:

                    std::max(function_returning_qsizetype(), 10LL)

                    Using 10LL is not portable. I don't really remember which type had this problem, but I once ran into a problem with these integer literals that did not have a solution for Windows, Linux, and macOS (yet). Starting from C++23 you have Z available which will be actually be portable for this use case (https://en.cppreference.com/w/cpp/language/integer_literal).

                    J 1 Reply Last reply 11 Sept 2024, 08:51
                    0
                    • S SimonSchroeder
                      11 Sept 2024, 06:26

                      @JonB said in Qt6 C++ compilation changes:

                      std::max(function_returning_qsizetype(), 10LL)

                      Using 10LL is not portable. I don't really remember which type had this problem, but I once ran into a problem with these integer literals that did not have a solution for Windows, Linux, and macOS (yet). Starting from C++23 you have Z available which will be actually be portable for this use case (https://en.cppreference.com/w/cpp/language/integer_literal).

                      J Offline
                      J Offline
                      JonB
                      wrote on 11 Sept 2024, 08:51 last edited by JonB 9 Nov 2024, 08:51
                      #10

                      @SimonSchroeder
                      What a mess trying to find a simple literal of the same type as something as basic as what QList::count() returns!

                      For my part I only have to support gcc.

                      I shan't be writing for (qsizetype i = 0LL; i < list.count(), I will be sticking with int. So one possibility would be to convert/cast the qsizetype to int for the std::max() so I can use a plain literal. But I think I will abandon std::max() for qMax() to avoid this ugliness.

                      S 1 Reply Last reply 11 Sept 2024, 09:09
                      0
                      • J JonB
                        11 Sept 2024, 08:51

                        @SimonSchroeder
                        What a mess trying to find a simple literal of the same type as something as basic as what QList::count() returns!

                        For my part I only have to support gcc.

                        I shan't be writing for (qsizetype i = 0LL; i < list.count(), I will be sticking with int. So one possibility would be to convert/cast the qsizetype to int for the std::max() so I can use a plain literal. But I think I will abandon std::max() for qMax() to avoid this ugliness.

                        S Offline
                        S Offline
                        sierdzio
                        Moderators
                        wrote on 11 Sept 2024, 09:09 last edited by
                        #11

                        I shan't be writing for (qsizetype i = 0LL; i < list.count(), I will be sticking with int.

                        It might fail for very large lists ;-) But for (qsizetype i = 0; i < list.count() should work just fine.

                        As for max, this is also an option if you like to type a lot:

                        std::max(jsonArray.count(), static_cast<qsizetype>(10)).
                        

                        (Z(:^

                        J 1 Reply Last reply 11 Sept 2024, 09:11
                        0
                        • S sierdzio
                          11 Sept 2024, 09:09

                          I shan't be writing for (qsizetype i = 0LL; i < list.count(), I will be sticking with int.

                          It might fail for very large lists ;-) But for (qsizetype i = 0; i < list.count() should work just fine.

                          As for max, this is also an option if you like to type a lot:

                          std::max(jsonArray.count(), static_cast<qsizetype>(10)).
                          
                          J Offline
                          J Offline
                          JonB
                          wrote on 11 Sept 2024, 09:11 last edited by JonB 9 Nov 2024, 09:13
                          #12

                          @sierdzio said in Qt6 C++ compilation changes:

                          It might fail for very large lists

                          Absolutely! But as you can see the kind of size I have in mind is 10. That is a long way away from 2 ^ 63 :)

                          static_cast<qsizetype>(10)

                          Of course! But I am simply not prepared to write to write that when comparing against 10!

                          J 1 Reply Last reply 11 Sept 2024, 11:08
                          0
                          • J JonB
                            11 Sept 2024, 09:11

                            @sierdzio said in Qt6 C++ compilation changes:

                            It might fail for very large lists

                            Absolutely! But as you can see the kind of size I have in mind is 10. That is a long way away from 2 ^ 63 :)

                            static_cast<qsizetype>(10)

                            Of course! But I am simply not prepared to write to write that when comparing against 10!

                            J Offline
                            J Offline
                            JoeCFD
                            wrote on 11 Sept 2024, 11:08 last edited by
                            #13

                            @JonB This change matches the one in C++. I used to have loops like

                            std::vector< something > vec;
                            for ( unsigned idx = 0; idx < vec.size(); ++idx ) 
                            {
                            }
                            

                            In new C++

                            std::vector< something > vec;
                            for ( size_t idx = 0; idx < vec.size(); ++idx ) 
                            {
                            }
                            

                            If you do not like the casting, I guess you can replace your loop with

                            for ( auto const & element : your list )
                            {
                            }
                            

                            Simpler.

                            J 1 Reply Last reply 11 Sept 2024, 12:15
                            0
                            • J JoeCFD
                              11 Sept 2024, 11:08

                              @JonB This change matches the one in C++. I used to have loops like

                              std::vector< something > vec;
                              for ( unsigned idx = 0; idx < vec.size(); ++idx ) 
                              {
                              }
                              

                              In new C++

                              std::vector< something > vec;
                              for ( size_t idx = 0; idx < vec.size(); ++idx ) 
                              {
                              }
                              

                              If you do not like the casting, I guess you can replace your loop with

                              for ( auto const & element : your list )
                              {
                              }
                              

                              Simpler.

                              J Offline
                              J Offline
                              JonB
                              wrote on 11 Sept 2024, 12:15 last edited by JonB 9 Nov 2024, 12:17
                              #14

                              @JoeCFD
                              I object to using size_t (should really be ssize_t which is what qsizetype is) as my "default" loop counter type when I have thousands of existing occurrences using int! (Having said that, just to be clear, the change in type/size does not prevent me from using int even now, so I don't have to change everything. It is something like std::max() which is affected/falls foul of the new definition.)

                              Your last case is more or less what I use when iterating and I do not need the index inside the loop. But the integral counter is required/easier when you do need to know the index value.

                              J 1 Reply Last reply 11 Sept 2024, 13:52
                              0
                              • J JonB
                                11 Sept 2024, 12:15

                                @JoeCFD
                                I object to using size_t (should really be ssize_t which is what qsizetype is) as my "default" loop counter type when I have thousands of existing occurrences using int! (Having said that, just to be clear, the change in type/size does not prevent me from using int even now, so I don't have to change everything. It is something like std::max() which is affected/falls foul of the new definition.)

                                Your last case is more or less what I use when iterating and I do not need the index inside the loop. But the integral counter is required/easier when you do need to know the index value.

                                J Offline
                                J Offline
                                JoeCFD
                                wrote on 11 Sept 2024, 13:52 last edited by JoeCFD 9 Nov 2024, 13:56
                                #15

                                @JonB from here
                                size(C++17)
                                ssize(C++20)
                                Something new for me. Good to know.

                                https://en.cppreference.com/w/cpp/iterator/size

                                Recently I built a project on Windows with C++ 14. size_t is needed to replace int for std::vector in the build warnings.

                                when you need an index

                                int index{}; (if you prefer int)
                                for ( auto const & element : your list )
                                {
                                     do something with index
                                     index++;
                                }
                                
                                J 1 Reply Last reply 11 Sept 2024, 14:06
                                0
                                • J JoeCFD
                                  11 Sept 2024, 13:52

                                  @JonB from here
                                  size(C++17)
                                  ssize(C++20)
                                  Something new for me. Good to know.

                                  https://en.cppreference.com/w/cpp/iterator/size

                                  Recently I built a project on Windows with C++ 14. size_t is needed to replace int for std::vector in the build warnings.

                                  when you need an index

                                  int index{}; (if you prefer int)
                                  for ( auto const & element : your list )
                                  {
                                       do something with index
                                       index++;
                                  }
                                  
                                  J Offline
                                  J Offline
                                  JonB
                                  wrote on 11 Sept 2024, 14:06 last edited by JonB 9 Nov 2024, 14:41
                                  #16

                                  @JoeCFD
                                  Sorry if you think I am being difficult, but I'm not going to write a "for-element-in-list" loop and then maintain a separate index counter! One or the other!

                                  Besides I was talking about existing code already written. But as a I say I can still use an int loop counter at Qt6, at least with gcc, without warning. It's just something like std::max() which barfs.

                                  We can debate further if you wish, but I do get that Qt etc. need to change to long long for size/count/array-indexing etc. I just don't like how messy it is making it (for std::max() at least) to pass a simple, numeric, non-qualified literal.

                                  J 1 Reply Last reply 11 Sept 2024, 14:37
                                  0
                                  • J JonB
                                    11 Sept 2024, 14:06

                                    @JoeCFD
                                    Sorry if you think I am being difficult, but I'm not going to write a "for-element-in-list" loop and then maintain a separate index counter! One or the other!

                                    Besides I was talking about existing code already written. But as a I say I can still use an int loop counter at Qt6, at least with gcc, without warning. It's just something like std::max() which barfs.

                                    We can debate further if you wish, but I do get that Qt etc. need to change to long long for size/count/array-indexing etc. I just don't like how messy it is making it (for std::max() at least) to pass a simple, numeric, non-qualified literal.

                                    J Offline
                                    J Offline
                                    JoeCFD
                                    wrote on 11 Sept 2024, 14:37 last edited by
                                    #17

                                    @JonB We learn more from discussions. I do not feel you are difficult in any way.

                                    1 Reply Last reply
                                    1

                                    3/17

                                    9 Sept 2024, 16:06

                                    topic:navigator.unread, 14
                                    • Login

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