https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120232

            Bug ID: 120232
           Summary: Are _GLIBCXX_USE_C99_MATH autoconf checks for
                    std::fpclassify etc. too strict?
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

Currently the FP classification functions that come from C99 are guarded by:

#if _GLIBCXX_USE_C99_MATH
#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC

// These are possible macros imported from C99-land.
#undef fpclassify
#undef isfinite
#undef isinf
#undef isnan
#undef isnormal
#undef signbit
#undef isgreater
#undef isgreaterequal
#undef isless
#undef islessequal
#undef islessgreater
#undef isunordered

where _GLIBCXX_USE_C99_MATH is decided by configure tests like:

    # Check for the existence of <math.h> generic macros used if C99 is
enabled.
    AC_CACHE_CHECK([for ISO C99 generic macro support in <math.h> for C++11],
    glibcxx_cv_c99_math_cxx11, [
      GCC_TRY_COMPILE_OR_LINK(
        [#include <math.h>
         volatile double d1, d2;
         volatile int i;],
        [i = fpclassify(d1);
         i = isfinite(d1);
         i = isinf(d1);
         i = isnan(d1);
         i = isnormal(d1);
         i = signbit(d1);
         i = isgreater(d1, d2);
         i = isgreaterequal(d1, d2);
         i = isless(d1, d2);
         i = islessequal(d1, d2);
         i = islessgreater(d1, d2);
         i = islessgreater(d1, d2);
         i = isunordered(d1, d2);
        ], [glibcxx_cv_c99_math_cxx11=yes], [glibcxx_cv_c99_math_cxx11=no])
    ])
    if test x"$glibcxx_cv_c99_math_cxx11" = x"yes"; then
      AC_DEFINE(_GLIBCXX11_USE_C99_MATH, 1,
        [Define if C99 generic macros in <math.h> should be imported
        in <cmath> in namespace std for C++11.])
    fi


(The configure tests actually define _GLIBCXX98_USE_C99_MATH and
_GLIBCXX11_USE_C99_MATH and then _GLIBCXX_USE_C99_MATH is defined in terms of
those, depending on the value of __cplusplus during preprocessing).

I don't think we really need to depend on the presence of those classification
macros in libc, because we define the std::xxx versions as functions (and
function templates) in terms of compiler built-ins. I don't think those
built-ins ever expand to something that uses libc functions, I think they're
always expanded directly by the compiler.

So all we really depend on is the FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL
and FP_ZERO macros being defined by libc. We could remove the configure tests
and just check for those macros directly in the <cmath> header.

In practice this probably won't make much difference, because if libc defines
those FP_xxx macros then it probably also defines the classification functions
that use them. So this isn't likely to enable std::fpclassify etc. on more
targets (except maybe for a fork like avr-libstdcpp which doesn't use the
autoconf checks and so currently never defines std::fpclassify, see
https://github.com/modm-io/avr-libstdcpp/issues/40 for more). But it would mean
we can remove two configure tests, and the preprocessor logic to define
_GLIBCXX_USE_C99_MATH based on the 98/11 macros from configure. That
simplification might be worthwhile.

See https://gcc.gnu.org/onlinedocs/gcc/Floating-Point-Format-Builtins.html for
details of the built-ins.

Reply via email to