From 759af3e5ad1520937955985bbcfee26f5a400e0f Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 20 Apr 2017 22:30:56 +0200 Subject: Centralize the check that the floating point implementation follows IEEE754 C++ does not specify which kind of floating point implementation is being used. The C Standard doesn't either, but it includes a normative reference for implementations adoping it (ISO/IEC 9899:2011 Annex F). There are a few existing checks in qfloat16.cpp; move them to qglobal.cpp (next to the other, similar checks), and improve them by actually checking that the radix used for floating point numbers is 2. Change-Id: I704a3a8efeb51014b3be23fb236654d647a6f44f Reviewed-by: Lars Knoll --- src/corelib/global/qfloat16.cpp | 18 ------------------ src/corelib/global/qglobal.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp index 1de1ae65fb..314a0addd1 100644 --- a/src/corelib/global/qfloat16.cpp +++ b/src/corelib/global/qfloat16.cpp @@ -59,24 +59,6 @@ QT_BEGIN_NAMESPACE \since 5.9 */ -Q_STATIC_ASSERT_X(sizeof(float) == sizeof(quint32), - "qfloat16 assumes that floats are 32 bits wide"); - -// There are a few corner cases regarding denormals where GHS compiler is relying -// hardware behavior that is not IEC 559 compliant. Therefore the compiler -// reports std::numeric_limits::is_iec559 as false. This is all right -// according to our needs. - -#if !defined(Q_CC_GHS) -Q_STATIC_ASSERT_X(std::numeric_limits::is_iec559, - "Only works with IEEE 754 floating point"); -#endif - -Q_STATIC_ASSERT_X(std::numeric_limits::has_infinity && - std::numeric_limits::has_quiet_NaN && - std::numeric_limits::has_signaling_NaN, - "Only works with IEEE 754 floating point"); - /*! Returns true if the \c qfloat16 \a {f} is equivalent to infinity. \relates diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 6de03d73b3..150ae7cf49 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -112,6 +112,33 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n); Q_STATIC_ASSERT_X(sizeof(int) == 4, "Qt assumes that int is 32 bits"); Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits"); Q_STATIC_ASSERT_X(QT_POINTER_SIZE == sizeof(void *), "QT_POINTER_SIZE defined incorrectly"); +Q_STATIC_ASSERT_X(sizeof(float) == 4, "Qt assumes that float is 32 bits"); + +// While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011 +// Annex F (C11, normative for C++11), there are a few corner cases regarding +// denormals where GHS compiler is relying hardware behavior that is not IEC +// 559 compliant. So split the check in several subchecks. + +// On GHC the compiler reports std::numeric_limits::is_iec559 as false. +// This is all right according to our needs. +#if !defined(Q_CC_GHS) +Q_STATIC_ASSERT_X(std::numeric_limits::is_iec559, + "Qt assumes IEEE 754 floating point"); +#endif + +// Technically, presence of NaN and infinities are implied from the above check, +// but double checking our environment doesn't hurt... +Q_STATIC_ASSERT_X(std::numeric_limits::has_infinity && + std::numeric_limits::has_quiet_NaN && + std::numeric_limits::has_signaling_NaN, + "Qt assumes IEEE 754 floating point"); + +// is_iec559 checks for ISO/IEC/IEEE 60559:2011 (aka IEEE 754-2008) compliance, +// but that allows for a non-binary radix. We need to recheck that. +// Note how __STDC_IEC_559__ would instead check for IEC 60559:1989, aka +// ANSI/IEEE 754−1985, which specifically implies binary floating point numbers. +Q_STATIC_ASSERT_X(std::numeric_limits::radix == 2, + "Qt assumes binary IEEE 754 floating point"); /*! \class QFlag -- cgit v1.2.3