[Interest] Operator QMap<uint, uint>[] is casting to int?

Thiago Macieira thiago.macieira at intel.com
Wed May 8 07:56:16 CEST 2019

On Tuesday, 7 May 2019 14:25:05 PDT Roland Hughes wrote:
> > If there's ever an STL2 (std2 namespace), it'll use signed.
> It's not just mixing C++ APIs. It is interfacing with devices which use
> unsigned octates in groups for the size followed by a contiguous block
> of octates for the data. When they accept text input it has to be sent
> this way and when they communicate text responses it comes back this way.

Data is different. std::byte is unsigned and "unsigned char" is the actual 
definition of byte. QByteArray should actually get an API to treat its 
contents as bytes, not just chars.

But we weren't talking about data, we were talking about metadata: sizes, 
indices, offsets.

> There are also the big data blocks like X-RAY/MRI images and such which
> need to be loaded into larger than signed int containers for manipulation.

Then you use a 64-bit signed integer for that. That's why Qt uses qint64 for 
file sizes, regardless of architecture. 

I can't think of a single use-case that would require the use of all 64 bits 
for the number, instead of 63 and leaving one for the sign. And if you really 
needed to represent numbers over 2^63, it's quite likely you need more than 
2^64 soon, so you had better come up with your own BigInt class for storing 
the information.

Quite frankly, the only reason to use 64-bit unsigned is to use the type as a 
bit pattern storage, such as what QRandomGenerator64::generate() returns.

> I haven't dug under the hood but I wonder if this impacts memory mapping of
> files. Maybe not if there is no container.

Absolutely not. You'd need to have files bigger than 2^63 for that to make 
sense. And mmap takes an off_t as the offset of the file to be mapped, which 
is a signed type.

> The ptrdiff_t comment earlier is a red herring.
> https://en.cppreference.com/w/cpp/types/ptrdiff_t
> typedef /*implementation-defined*/ ptrdiff_t;

In theory, sizeof(ptrdiff_t) and sizeof(size_t) and sizeof(void*) do not need 
to be the same. In fact, the size of the pointer was indeed different on 16-
bit DOS.

But in practice, in all modern architectures, and especially in all 
architectures Qt runs, has run, and will likely ever run, the three have the 
same size. And because of that, the size of the largest object and largest 
memory allocation is half the virtual memory address space.

It is possible to mmap() more than 2 GB of a file in a 32-bit Linux system, 
but a memory map is not a C++ object or a C++ memory allocation.

> Some shops won't or cannot let you use an int.
> If they are changing from int to q-whatever defined type there will
> probably be some compilation cleanup anyway so unsigned wouldn't be bad
> unless someone is cheating somewhere and initializing size to -1

qsizetype is signed and will remain so. We want to transition Qt containers to 
support more than 2 GB on 64-bit systems, so we want to use qsizetype. What's 
missing is implementing this and finding all the wrong casts.

PS: would you please reply with the correct subject?

Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel System Software Products

More information about the Interest mailing list