This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug math/19439] New: Unix98 isinf and isnan functions conflict with C++11


https://sourceware.org/bugzilla/show_bug.cgi?id=19439

            Bug ID: 19439
           Summary: Unix98 isinf and isnan functions conflict with C++11
           Product: glibc
           Version: 2.22
            Status: NEW
          Severity: normal
          Priority: P2
         Component: math
          Assignee: unassigned at sourceware dot org
          Reporter: jwakely.gcc at gmail dot com
  Target Milestone: ---

bits/mathcalls.h defines:

#ifdef __USE_MISC
/* Return 0 if VALUE is finite or NaN, +1 if it
   is +Infinity, -1 if it is -Infinity.  */
__MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));

and:

#if defined __USE_MISC || defined __USE_XOPEN
/* Return nonzero if VALUE is not a number.  */
__MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));

For C99 programs these functions are hidden by the genericis inf and isnan
macros. However C++11 defines isinf and isnan with the same semantics as C99
but requires that they are functions not macros, see C++11 26.8 [c.math]
paragraph 10.

In order to meet that requirement libstdc++ does:

#include <math.h>
#undef isinf
#undef isnan
namespace std {
  bool isinf(float);
  bool isinf(double);
  bool isinf(long double);
  // similarly for isnan
}

However the #undef only removes the C99 macro, the obsolete Unix98 functions
remain defined. This then results in a conflict for perfectly valid C++11
programs:

#include <cmath>

using std::isinf;
using std::isnan;

double d1 = isinf(1.0);
double d2 = isnan(1.0);


d.cc:3:12: error: âconstexpr bool std::isinf(double)â conflicts with a previous
declaration
 using std::isinf;
            ^
In file included from /usr/include/features.h:365:0,
                 from
/usr/include/c++/5.3.1/x86_64-redhat-linux/bits/os_defines.h:39,
                 from
/usr/include/c++/5.3.1/x86_64-redhat-linux/bits/c++config.h:2255,
                 from /usr/include/c++/5.3.1/cmath:41,
                 from d.cc:1:
/usr/include/bits/mathcalls.h:201:1: note: previous declaration âint
isinf(double)â
 __MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));
 ^
d.cc:4:12: error: âconstexpr bool std::isnan(double)â conflicts with a previous
declaration
 using std::isnan;
            ^
In file included from /usr/include/features.h:365:0,
                 from
/usr/include/c++/5.3.1/x86_64-redhat-linux/bits/os_defines.h:39,
                 from
/usr/include/c++/5.3.1/x86_64-redhat-linux/bits/c++config.h:2255,
                 from /usr/include/c++/5.3.1/cmath:41,
                 from d.cc:1:
/usr/include/bits/mathcalls.h:234:1: note: previous declaration âint
isnan(double)â
 __MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
 ^

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891 and its duplicates.

To solve this I am preparing a libstdc++ patch which detects the glibc isinf
and isnan functions and does this instead:

#include <math.h>
#undef isinf
#undef isnan
namespace std {
  bool isinf(float);
#ifdef _GLIBCXX_HAVE_OBSOLETE_ISINF_ISNAN
  using ::isinf;
#else
  bool isinf(double);
#endif
  bool isinf(long double);
  // similarly for isnan
}

This prevents the error, but is not correct because it means that the
isinf(double) and isnan(double) overloads return int not bool, as required by
the standard.

In addition to my libstdc++ patch to workaround the compilation error when
using existing glibc releases I propose fixing future releases of glibc so that
the obsolete functions are not declared for C++11 and later, allowing libstdc++
to define the correct signatures.

This patch implements that proposal, leaving the obsolete functions defined for
C++98 code, because they do not conflict with any standard function in C++98,
and this preserves backwards compatibility for C++98 programs that might be
relying on them.

diff --git a/math/bits/mathcalls.h b/math/bits/mathcalls.h
index b82c373..c0e24e1 100644
--- a/math/bits/mathcalls.h
+++ b/math/bits/mathcalls.h
@@ -196,9 +196,11 @@ __MATHDECL_1 (int,__finite,, (_Mdouble_ __value))
__attribute__ ((__const__));
 _Mdouble_END_NAMESPACE

 #ifdef __USE_MISC
+#if !defined __cplusplus || __cplusplus < 201103L /* Conflicts with C++11.  */
 /* Return 0 if VALUE is finite or NaN, +1 if it
    is +Infinity, -1 if it is -Infinity.  */
 __MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__ ((__const__));
+#endif

 /* Return nonzero if VALUE is finite and not NaN.  */
 __MATHDECL_1 (int,finite,, (_Mdouble_ __value)) __attribute__ ((__const__));
@@ -230,9 +232,11 @@ __END_NAMESPACE_C99
 __MATHDECL_1 (int,__isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));

 #if defined __USE_MISC || (defined __USE_XOPEN && !defined __USE_XOPEN2K)
+#if !defined __cplusplus || __cplusplus < 201103L /* Conflicts with C++11.  */
 /* Return nonzero if VALUE is not a number.  */
 __MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
 #endif
+#endif

 #if defined __USE_MISC || (defined __USE_XOPEN && __MATH_DECLARING_DOUBLE)
 /* Bessel functions.  */

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]