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

Inconsistent definition of qintptr and quintptr

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Do
    • Icon: Not Evaluated Not Evaluated
    • None
    • 6.6.1
    • Core: Other
    • None

      qintptr and quintptr are defined in the Qt documentation as:

      Integral type for representing pointers in a [un]signed integer (useful for hashing, etc.)."

      This matches the definition of std::intptr_t and std::uintptr_t in the C (and therefore C++) standard:

      The following type designates a [un]signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer.

      Therefore I'd expect that quintptr is exactly the same time as std::uintptr_t and std::size_t. Similar I'd expect qintptr to be identical to std::intptr_t and std::ptrdiff_t.

      This assumption is true on Windows. It doesn't hold on Linux.

      Qt should be consistent with the C++ standard.
      Even more it should be consistent with itself among supported platforms.

      Test program:

      #include <QtGlobal>
      
      #include <iostream>
      
      #define SHOW(What) std::cout << "  " #What ": " << (What) << std::endl;
      
      int main(int argc, char *argv[])
      {
          std::cout << "Environment:" << std::endl;
          SHOW(COMPILER_ID);
          SHOW(PLATFORM);
          SHOW(QT_VERSION_STR);
      
          std::cout << "Qt types vs. standard types" << std::endl;
          SHOW((std::is_same_v<quintptr, std::size_t>));
          SHOW((std::is_same_v<qintptr,  std::ptrdiff_t>));
          SHOW((std::is_same_v<quintptr, std::uintptr_t>));
          SHOW((std::is_same_v<qintptr,  std::intptr_t>));
      
          std::cout << "Standard types" << std::endl;
          SHOW((std::is_same_v<std::size_t,    std::uintptr_t>));
          SHOW((std::is_same_v<std::ptrdiff_t, std::intptr_t>));
      
          std::cout << "Underlaying types" << std::endl;
          SHOW((std::is_same_v<std::size_t, unsigned long>));
          SHOW((std::is_same_v<std::size_t, unsigned long long>));
          SHOW((std::is_same_v<std::ptrdiff_t, long>));
          SHOW((std::is_same_v<std::ptrdiff_t, long long>));
          SHOW((std::is_same_v<std::uintptr_t, unsigned long>));
          SHOW((std::is_same_v<std::uintptr_t, unsigned long long>));
          SHOW((std::is_same_v<std::intptr_t, long>));
          SHOW((std::is_same_v<std::intptr_t, long long>));
      
          return 0;
      }
      

      On Windows it produces the following output for:

      • MSVC 19.38.33133.0
      • Clang 17.0.4/CLANG64
      • CGCC 13.2.0/MinGW64
      • GCC 13.2.0/UCRT64
      Environment:
        COMPILER_ID: Clang 17.0.4
        PLATFORM: Windows 10.0.22621 CLANG64
        QT_VERSION_STR: 6.6.0
      Qt types vs. standard types
        (std::is_same_v<quintptr, std::size_t>): 1
        (std::is_same_v<qintptr, std::ptrdiff_t>): 1
        (std::is_same_v<quintptr, std::uintptr_t>): 1
        (std::is_same_v<qintptr, std::intptr_t>): 1
      Standard types
        (std::is_same_v<std::size_t, std::uintptr_t>): 1
        (std::is_same_v<std::ptrdiff_t, std::intptr_t>): 1
      Underlaying types
        (std::is_same_v<std::size_t, unsigned long>): 0
        (std::is_same_v<std::size_t, unsigned long long>): 1
        (std::is_same_v<std::ptrdiff_t, long>): 0
        (std::is_same_v<std::ptrdiff_t, long long>): 1
        (std::is_same_v<std::uintptr_t, unsigned long>): 0
        (std::is_same_v<std::uintptr_t, unsigned long long>): 1
        (std::is_same_v<std::intptr_t, long>): 0
        (std::is_same_v<std::intptr_t, long long>): 1
      

      In contrast on Linux it produces:

      Environment:
        COMPILER_ID: GNU 12.2.0
        PLATFORM: Linux 5.15.133.1-microsoft-standard-WSL2 
        QT_VERSION_STR: 6.4.2
      Qt types vs. standard types
        (std::is_same_v<quintptr, std::size_t>): 0
        (std::is_same_v<qintptr, std::ptrdiff_t>): 0
        (std::is_same_v<quintptr, std::uintptr_t>): 0
        (std::is_same_v<qintptr, std::intptr_t>): 0
      Standard types
        (std::is_same_v<std::size_t, std::uintptr_t>): 1
        (std::is_same_v<std::ptrdiff_t, std::intptr_t>): 1
      Underlaying types
        (std::is_same_v<std::size_t, unsigned long>): 1
        (std::is_same_v<std::size_t, unsigned long long>): 0
        (std::is_same_v<std::ptrdiff_t, long>): 1
        (std::is_same_v<std::ptrdiff_t, long long>): 0
        (std::is_same_v<std::uintptr_t, unsigned long>): 1
        (std::is_same_v<std::uintptr_t, unsigned long long>): 0
        (std::is_same_v<std::intptr_t, long>): 1
        (std::is_same_v<std::intptr_t, long long>): 0
      

      Minimal testcase: quintptr-bug.tar.gz

        1. quintptr-bug.tar.gz
          1 kB
          Mathias Hasselmann
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            thiago Thiago Macieira
            hasselmm Mathias Hasselmann
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes