Work around VS2015/17 bitset + qfloat16.h compiler bug

[ChangeLog][QtCore][Global] Added the QT_NO_FLOAT16_OPERATORS macro in
order to work around a Microsoft <= VS2017 compiler bug that is
exposed when using std::bitset along with any Qt header that includes
<qfloat16.h>.

This is fixed in MSVC 2019[1], but the workaround is needed for
earlier versions.

In this case, cl.exe fails with
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\bitset(270): error C2666: 'operator /': 10 overloads have similar conversions
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qsize.h(364): note: could be 'const QSizeF operator /(const QSizeF &,qreal)'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qsize.h(194): note: or       'const QSize operator /(const QSize &,qreal)'
    c:\qt\5.12.0\msvc2017_64\include\qtcore\qmargins.h(427): note: or       'QMarginsF operator /(const QMarginsF &,qreal)'
    c:\qt\5.12.0\msvc2017_64\include\qtcore\qmargins.h(213): note: or       'QMargins operator /(const QMargins &,qreal)'
    c:\qt\5.12.0\msvc2017_64\include\qtcore\qmargins.h(207): note: or       'QMargins operator /(const QMargins &,int)'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(205): note: or       'double operator /(int,qfloat16) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(205): note: or       'double operator /(qfloat16,int) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(195): note: or       'float operator /(float,qfloat16) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(195): note: or       'float operator /(qfloat16,float) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(194): note: or       'double operator /(double,qfloat16) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(194): note: or       'double operator /(qfloat16,double) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(193): note: or       'long double operator /(long double,qfloat16) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(193): note: or       'long double operator /(qfloat16,long double) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qfloat16.h(176): note: or       'qfloat16 operator /(qfloat16,qfloat16) noexcept'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qpoint.h(402): note: or       'const QPointF operator /(const QPointF &,qreal)'
    C:\Qt\5.12.0\msvc2017_64\include\QtCore/qpoint.h(206): note: or       'const QPoint operator /(const QPoint &,qreal)'
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\bitset(270): note: or       'built-in C++ operator/(::size_t, )'
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\bitset(270): note: while trying to match the argument list '(::size_t, )'
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\bitset(266): note: while compiling class template member function 'std::bitset<8> &std::bitset<8>::set(::size_t,bool)'
    C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\include\bitset(39): note: see reference to function template instantiation 'std::bitset<8> &std::bitset<8>::set(::size_t,bool)' being compiled
    ..\Qt5.12.0-C2666\main.cpp(7): note: see reference to class template instantiation 'std::bitset<8>' being compiled

Invoke this workaround by defining the macro QT_NO_FLOAT16_OPERATORS
in user code prior to the inclusion of Qt includes in a translation
unit.

Arithmetic operators from qfloat16 will then not be present in that
compilation unit.

[1] https://developercommunity.visualstudio.com/content/problem/406329/compiler-error-c2666-when-using-stdbitset-and-cust.html

Task-number: QTBUG-72073
Change-Id: I58f8400bf933ad781d4213731695e20e0c482166
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
bb10
Keith Kyzivat 2019-03-15 12:07:42 -04:00
parent 3159845c9c
commit b7edc811ec
2 changed files with 17 additions and 0 deletions

View File

@ -64,6 +64,19 @@ QT_BEGIN_NAMESPACE
\since 5.9
*/
/*!
\macro QT_NO_FLOAT16_OPERATORS
\relates <QFloat16>
\since 5.12.4
Defining this macro disables the arithmetic operators for qfloat16.
This is only necessary on Visual Studio 2017 (and earlier) when including
\c {<QFloat16>} and \c{<bitset>} in the same translation unit, which would
otherwise cause a compilation error due to a toolchain bug (see
[QTBUG-72073]).
*/
/*!
Returns true if the \c qfloat16 \a {f} is equivalent to infinity.
\relates <QFloat16>

View File

@ -83,7 +83,9 @@ private:
Q_CORE_EXPORT static const quint32 shifttable[];
friend bool qIsNull(qfloat16 f) Q_DECL_NOTHROW;
#if !defined(QT_NO_FLOAT16_OPERATORS)
friend qfloat16 operator-(qfloat16 a) Q_DECL_NOTHROW;
#endif
};
Q_DECLARE_TYPEINFO(qfloat16, Q_PRIMITIVE_TYPE);
@ -165,6 +167,7 @@ inline qfloat16::operator float() const Q_DECL_NOTHROW
}
#endif
#if !defined(QT_NO_FLOAT16_OPERATORS)
inline qfloat16 operator-(qfloat16 a) Q_DECL_NOTHROW
{
qfloat16 f;
@ -246,6 +249,7 @@ QF16_MAKE_BOOL_OP_INT(!=)
#undef QF16_MAKE_BOOL_OP_INT
QT_WARNING_POP
#endif // QT_NO_FLOAT16_OPERATORS
/*!
\internal