bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: signbit #define'd causes compilation error in octave


From: Bruno Haible
Subject: Re: signbit #define'd causes compilation error in octave
Date: Sat, 22 Oct 2011 14:02:35 +0200
User-agent: KMail/1.13.6 (Linux/2.6.37.6-0.5-desktop; KDE/4.6.0; x86_64; ; )

Eric Blake wrote:
> in C++, we could avoid the macros and 
> instead have three overloaded functions named signbit which operate on 
> the correct types, so as not to pollute the namespace with a macro. 
> POSIX does not speak to C++ compliance, so using overloads instead of a 
> macro for C++ does not cause any non-compliance issues.

Good idea, and thanks for checking that POSIX allows this approach in C++.

Implemented as follows:


2011-10-22  Bruno Haible  <address@hidden>

        isfinite, isinf, isnan, signbit: Don't define as a macro in C++.
        * lib/math.in.h (_GL_MATH_CXX_REAL_FLOATING_DECL_1,
        _GL_MATH_CXX_REAL_FLOATING_DECL_2): nEW MACROS.
        (isfinite, isinf, isnan, signbit): In C++, define as overloaded
        functions, not as a macro.
        * tests/test-math-c++.cc (REAL_FLOATING_CHECK, OVERLOADED_CHECK): New
        macros.
        (isfinite, isinf, isnan, signbit): Check overloaded functions and
        absence of macro.
        Suggested by Eric Blake.
        Reported by Michael Goffioul <address@hidden>.

--- lib/math.in.h.orig  Sat Oct 22 13:47:30 2011
+++ lib/math.in.h       Sat Oct 22 13:37:40 2011
@@ -35,6 +35,44 @@
 
 /* The definition of _GL_WARN_ON_USE is copied here.  */
 
+#ifdef __cplusplus
+/* Helper macros to define type-generic function FUNC as overloaded functions,
+   rather than as macros like in C.  POSIX declares these with an argument of
+   real-floating (that is, one of float, double, or long double).  */
+# define _GL_MATH_CXX_REAL_FLOATING_DECL_1(func) \
+static inline int                                                   \
+_gl_cxx_ ## func ## f (float f)                                     \
+{                                                                   \
+  return func (f);                                                  \
+}                                                                   \
+static inline int                                                   \
+_gl_cxx_ ## func ## d (double d)                                    \
+{                                                                   \
+  return func (d);                                                  \
+}                                                                   \
+static inline int                                                   \
+_gl_cxx_ ## func ## l (long double l)                               \
+{                                                                   \
+  return func (l);                                                  \
+}
+# define _GL_MATH_CXX_REAL_FLOATING_DECL_2(func) \
+inline int                                                          \
+func (float f)                                                      \
+{                                                                   \
+  return _gl_cxx_ ## func ## f (f);                                 \
+}                                                                   \
+inline int                                                          \
+func (double d)                                                     \
+{                                                                   \
+  return _gl_cxx_ ## func ## d (d);                                 \
+}                                                                   \
+inline int                                                          \
+func (long double l)                                                \
+{                                                                   \
+  return _gl_cxx_ ## func ## l (l);                                 \
+}
+#endif
+
 /* Helper macros to define a portability warning for the
    classification macro FUNC called with VALUE.  POSIX declares the
    classification macros with an argument of real-floating (that is,
@@ -1030,6 +1068,13 @@
     sizeof (x) == sizeof (double) ? gl_isfinited (x) : \
     gl_isfinitef (x))
 # endif
+# ifdef __cplusplus
+#  ifdef isfinite
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite)
+#   undef isfinite
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite)
+#  endif
+# endif
 #elif defined GNULIB_POSIXCHECK
 # if defined isfinite
 _GL_WARN_REAL_FLOATING_DECL (isfinite);
@@ -1050,6 +1095,13 @@
     sizeof (x) == sizeof (double) ? gl_isinfd (x) : \
     gl_isinff (x))
 # endif
+# ifdef __cplusplus
+#  ifdef isinf
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isinf)
+#   undef isinf
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf)
+#  endif
+# endif
 #elif defined GNULIB_POSIXCHECK
 # if defined isinf
 _GL_WARN_REAL_FLOATING_DECL (isinf);
@@ -1161,9 +1213,17 @@
     sizeof (x) == sizeof (double) ? __builtin_isnan ((double)(x)) : \
     __builtin_isnanf ((float)(x)))
 # endif
+# ifdef __cplusplus
+#  ifdef isnan
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isnan)
+#   undef isnan
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan)
+#  endif
+# else
 /* Ensure isnan is a macro.  */
-# ifndef isnan
-#  define isnan isnan
+#  ifndef isnan
+#   define isnan isnan
+#  endif
 # endif
 #elif defined GNULIB_POSIXCHECK
 # if defined isnan
@@ -1227,6 +1287,13 @@
     sizeof (x) == sizeof (double) ? gl_signbitd (x) : \
     gl_signbitf (x))
 # endif
+# ifdef __cplusplus
+#  ifdef signbit
+_GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit)
+#   undef signbit
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit)
+#  endif
+# endif
 #elif defined GNULIB_POSIXCHECK
 # if defined signbit
 _GL_WARN_REAL_FLOATING_DECL (signbit);
--- tests/test-math-c++.cc.orig Sat Oct 22 13:47:30 2011
+++ tests/test-math-c++.cc      Sat Oct 22 13:38:26 2011
@@ -23,6 +23,18 @@
 
 #include "signature.h"
 
+/* Signature check for a function that takes a real-floating argument.
+   Check that each overloaded function with the specified signature exists.  */
+#define REAL_FLOATING_CHECK(func,\
+                            rettype1, parameters1,\
+                            rettype2, parameters2,\
+                            rettype3, parameters3) \
+  OVERLOADED_CHECK (func, rettype1, parameters1, _1); \
+  OVERLOADED_CHECK (func, rettype2, parameters2, _2); \
+  OVERLOADED_CHECK (func, rettype3, parameters3, _3)
+#define OVERLOADED_CHECK(func, rettype, parameters, suffix) \
+  static rettype (* _GL_UNUSED signature_check_ ## func ## suffix) parameters \
+    = static_cast<rettype(*)parameters>(func)
 
 #if GNULIB_TEST_ACOSF
 SIGNATURE_CHECK (GNULIB_NAMESPACE::acosf, float, (float));
@@ -76,6 +88,24 @@
 SIGNATURE_CHECK (GNULIB_NAMESPACE::frexp, double, (double, int *));
 #endif
 //SIGNATURE_CHECK (GNULIB_NAMESPACE::hypot, double, (double, double));
+#if GNULIB_TEST_ISFINITE
+# ifdef isfinite
+#  error "isfinite should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (isfinite, int, (float), int, (double), int, (long 
double));
+#endif
+#if GNULIB_TEST_ISINF
+# ifdef isinf
+#  error "isinf should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (isinf, int, (float), int, (double), int, (long double));
+#endif
+#if GNULIB_TEST_ISNAN
+# ifdef isnan
+#  error "isnan should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (isnan, int, (float), int, (double), int, (long double));
+#endif
 //SIGNATURE_CHECK (GNULIB_NAMESPACE::j0, double, (double));
 //SIGNATURE_CHECK (GNULIB_NAMESPACE::j1, double, (double));
 //SIGNATURE_CHECK (GNULIB_NAMESPACE::jn, double, (int, double));
@@ -211,6 +241,13 @@
 SIGNATURE_CHECK (GNULIB_NAMESPACE::roundl, long double, (long double));
 #endif
 
+#if GNULIB_TEST_SIGNBIT
+# ifdef signbit
+#  error "signbit should not be a macro in C++"
+# endif
+REAL_FLOATING_CHECK (signbit, int, (float), int, (double), int, (long double));
+#endif
+
 #if GNULIB_TEST_SINL
 SIGNATURE_CHECK (GNULIB_NAMESPACE::sinl, long double, (long double));
 #endif

-- 
In memoriam Nunilo and Alodia <http://en.wikipedia.org/wiki/Nunilo_and_Alodia>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]