Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.9.4
-
None
-
openSUSE Leap 15.0
4.12.14-lp150.12.67-default
gcc (SUSE Linux) 7.4.1 20190424 [gcc-7-branch revision 270538]
QMake version 3.1
Using Qt version 5.9.4
-
-
1872d1a41de0d4994c799c8d7dd4e72aaf49c677 (qt/qtbase/5.13)
Description
The Qt behavior strongly suggests that if you have an enum acting like a set of flags and you’ve declared a QFlags type using Q_DECLARE_FLAGS macro, then you should apply the Q_FLAG macro to the enumeration itself, and not to the QFlags type.
- If you use Q_FLAG on the enum, then both the enum and corresponding QFlags are stringified by qDebug() properly. If you follow the documentation, QFlags is stringified properly while enum itself is not.
- If you use Q_FLAG on the enum, dumping a QFlags variable to qDebug() produces a string which looks like
QFlags<EnumName>(EnumValue)
, which is correct. If you follow the documentation, QDebug produces a string which looks like
QFlags<QFlagsName>(EnumValue)
, which is misleading and semantically wrong.
The QObject class reference says this:
It is typically used in a class definition to declare that values of a given enum can be used as flags and combined using the bitwise OR operator.
This is marginally acceptable in the sense that it can be understood that Q_FLAG should be applied to the enumeration itself. However, it’s followed by an example which does this:
...
Q_DECLARE_FLAGS(LoadHints, LoadHint)
Q_FLAG(LoadHints)
This error in documentation is so misleading that it confused the overwhelming majority of Qt developers themselves, which lead to 75% of Qt enums to be marked in a wrong way. Anyone can check this with a tiny program:
// BAD: outputs 1 instead of the name
qDebug() << Qt::AlignLeading;
// BAD (although somewhat acceptable): outputs
// QFlags<Qt::Alignment>(AlignLeading|AlignTrailing)
// instead of semantically correct
// QFlags<Qt::AlignmentFlag>(AlignLeading|AlignTrailing)
// or, which would be less cumbersome and easier to read,
// Qt::Alignment(AlignLeading|AlignTrailing)
qDebug() << Qt::Alignment(Qt::AlignLeading | Qt::AlignTrailing);
Please note that the attached SSCCE contains additional info.