[Development] 64-bit QFlags support

Thiago Macieira thiago.macieira at intel.com
Thu Aug 8 20:22:39 CEST 2024


See https://codereview.qt-project.org/c/qt/qtbase/+/580778

I'm working on the ability to support 64-bit QFlags. My solution for that is 
to have QFlags64 and keep sizeof(QFlags<T>) == 4 for any T. I have two reasons 
for that choice:

1) BC of QFlags in existing structures and parameters
I want to avoid a silly mistake in someone adding an extra enumerator and 
suddenly changing the size of the underlying enum from 4 to 8 bytes. Right 
now, you have this extra safety belt that QFlags will tell you that you did so 
and refuse to compile. To support 64-bit enums in QFlags, we need to remove 
it.

We may not consider this a problem. There is obviously no safety belt for non-
QFlags enums. Also, see https://gcc.godbolt.org/z/sxja1jxvY for example: I 
added an enum at the end and that made the enum increase to 8 bytes for IA-64 
C++ ABI systems, but it remained at 4 bytes for MSVC ABI, with just a warning 
about truncation. The latter is obviously a problem because the extra 
enumerator can't fit the variable and becomes 0. This means developers *must* 
add an explicit underlying type to the enumeration in order to use it as 64-
bit if you care for cross-platform compatibility. 

But you may not. All of KDE libraries and applications, for example, don't 
care about MSVC compatibility, nor will macOS or iOS or Android content.


2) moc extraction of 64-bit values onto the meta object
In order to support 64-bit QFlags, we need to store the high part somewhere. 
One way of doing this is to store the high part for ALL enums and QFlags, all 
of which right now are zeroes. This will increase the meta object's integer 
array by 4 bytes per enumerator. For QtCore, that's 10232 extra bytes. In all 
of qtbase, we have 4370 enumerators extracted to the meta objects.

The other way is to do it only for enums and QFlags that are 64-bit in the 
first place, using a bit in the QMetaEnum flags field to indicate that the enum 
in question is wider and which would allow adding QMetaEnum::is64Bit().

But in order to do that, moc needs to generate the data for those differently 
than the others and it does not parse the values of the enumeration. I don't 
think it's feasible to do so either, because the values may themselves be 
constants whose value moc could not find.

My solution is to have moc parse a new declaration Q_DECLARE_FLAGS64, which 
indicates the flag is 64-bit, and then generate different data. I have not 
implemented Q_FLAGS64 or Q_ENUM64 yet.


The two tie into each other: moc and QFlags64 require a new macro in order to 
work. But the needs are independent of each other: we can have 
Q_DECLARE_FLAGS64 declare a QFlags or we can have moc generate the same 
content for both macros, regardless of class.
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Principal Engineer - Intel DCAI Platform & System Engineering
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5152 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20240808/ae444fb1/attachment.bin>


More information about the Development mailing list