[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: isnan function conflicts with C++ standard library declarations
From: |
Bruno Haible |
Subject: |
Re: isnan function conflicts with C++ standard library declarations |
Date: |
Wed, 28 Aug 2019 10:46:19 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-159-generic; KDE/5.18.0; x86_64; ; ) |
Hi,
Martin Storsjö wrote:
> When the isnan function is enabled in gnulib, the added bits in math.h
> break if included in C++ translation units.
>
> A minimal reproducion example is available at
> https://martin.st/temp/gnulib-isnan-repro-0.0.0.tar.gz (preconfigured and
> directly buildable) and
> https://martin.st/temp/gnulib-isnan-repro-source.tar.gz (original source,
> requires running gnulib-tool and autoreconf).
>
> The error manifests both with GCC/libstdc++ and Clang/libc++, with error
> messages like these:
>
> In file included from myprog.cpp:2:0:
> lib/math.h: In function ‘int isnan(float)’:
> lib/math.h:2829:1: error: ‘int isnan(float)’ conflicts with a previous
> declaration
> _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan)
> ^
> In file included from /usr/include/c++/7/math.h:36:0,
> from lib/math.h:27,
> from myprog.cpp:2:
> /usr/include/c++/7/cmath:618:3: note: previous declaration ‘constexpr bool
> std::isnan(float)’
> isnan(float __x)
> ^~~~~
I reproduce the issue on mingw - thanks for a very nicely made
reproduction example -, and have applied the fix below.
> In file included from myprog.cpp:2:
> lib/math.h:2829:36: error: 'isnan' is missing exception specification
> 'throw()'
> _GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan)
> ^
> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/math.h:533:1:
> note:
> previous declaration is here
> isnan(float __lcpp_x) _NOEXCEPT { return __libcpp_isnan(__lcpp_x); }
> ^
Probably I should test this also on macOS and other platforms...
> This issue can crop up e.g. when trying to build gettext for mingw (which
> has got the gnulib isnan function bundled, even if it isn't used).
I'm regularly building gettext on mingw and haven't seen this issue. Therefore
thanks again for the reproduction example.
2019-08-28 Bruno Haible <address@hidden>
isfinite, isinf, isnan, signbit: Fix error in C++ mode on mingw.
Reported by Martin Storsjö <address@hidden> in
<https://lists.gnu.org/archive/html/bug-gnulib/2019-08/msg00075.html>.
* lib/math.in.h (_GL_MATH_CXX_REAL_FLOATING_DECL_2): Add more arguments.
(isfinite, isinf, isnan, signbit): On mingw, use an override through
'#define', because the inline definitions in the platform's <cmath>
cannot be overridden in another way.
diff --git a/lib/math.in.h b/lib/math.in.h
index 99a2c6a..8292650 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -67,20 +67,20 @@ _gl_cxx_ ## func ## l (long double l)
\
{ \
return func (l); \
}
-# define _GL_MATH_CXX_REAL_FLOATING_DECL_2(func) \
+# define _GL_MATH_CXX_REAL_FLOATING_DECL_2(func,rpl_func,rettype) \
_GL_BEGIN_NAMESPACE \
-inline int \
-func (float f) \
+inline rettype \
+rpl_func (float f) \
{ \
return _gl_cxx_ ## func ## f (f); \
} \
-inline int \
-func (double d) \
+inline rettype \
+rpl_func (double d) \
{ \
return _gl_cxx_ ## func ## d (d); \
} \
-inline int \
-func (long double l) \
+inline rettype \
+rpl_func (long double l) \
{ \
return _gl_cxx_ ## func ## l (l); \
} \
@@ -2207,7 +2207,14 @@ _GL_EXTERN_C int gl_isfinitel (long double x);
# if defined isfinite || defined GNULIB_NAMESPACE
_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isfinite)
# undef isfinite
-_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite)
+# if defined __MINGW32__
+ /* This platform's <cmath> defines isfinite through a set of inline
+ functions. */
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, rpl_isfinite, bool)
+# define isfinite rpl_isfinite
+# else
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isfinite, isfinite, bool)
+# endif
# endif
# endif
#elif defined GNULIB_POSIXCHECK
@@ -2234,7 +2241,14 @@ _GL_EXTERN_C int gl_isinfl (long double x);
# if defined isinf || defined GNULIB_NAMESPACE
_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isinf)
# undef isinf
-_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf)
+# if defined __MINGW32__
+ /* This platform's <cmath> defines isinf through a set of inline
+ functions. */
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf, rpl_isinf, bool)
+# define isinf rpl_isinf
+# else
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isinf, isinf, bool)
+# endif
# endif
# endif
#elif defined GNULIB_POSIXCHECK
@@ -2352,7 +2366,14 @@ _GL_EXTERN_C int rpl_isnanl (long double x)
_GL_ATTRIBUTE_CONST;
# if defined isnan || defined GNULIB_NAMESPACE
_GL_MATH_CXX_REAL_FLOATING_DECL_1 (isnan)
# undef isnan
-_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan)
+# if defined __MINGW32__
+ /* This platform's <cmath> defines isnan through a set of inline
+ functions. */
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, rpl_isnan, bool)
+# define isnan rpl_isnan
+# else
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (isnan, isnan, bool)
+# endif
# endif
# else
/* Ensure isnan is a macro. */
@@ -2428,7 +2449,14 @@ _GL_EXTERN_C int gl_signbitl (long double arg);
# if defined signbit || defined GNULIB_NAMESPACE
_GL_MATH_CXX_REAL_FLOATING_DECL_1 (signbit)
# undef signbit
-_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit)
+# if defined __MINGW32__
+ /* This platform's <cmath> defines signbit through a set of inline
+ functions. */
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, rpl_signbit, bool)
+# define signbit rpl_signbit
+# else
+_GL_MATH_CXX_REAL_FLOATING_DECL_2 (signbit, signbit, bool)
+# endif
# endif
# endif
#elif defined GNULIB_POSIXCHECK