[Bug libstdc++/19322] New: std::isnan<>() is broken on FreeBSD
gcc-bugzilla at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Fri Jan 7 23:07:00 GMT 2005
(Link to original mail: http://gcc.gnu.org/ml/libstdc++/2005-01/msg00059.html)
On FreeBSD 5.3, if I run the following test program (compiled w/ system gcc,
which is 3.4.2; or a hand-compiled current CVS snapshot):
#include <iostream>
#include <cmath>
int main(void)
{
std::cout << std::isnan(3.0) << '\n';
return 0;
}
I get a segfault:
lorinder$ g++ x.cc
lorinder$ ./a.out
Segmentation fault (core dumped)
There is no problem on Linux. The segfault happens as well if I add
-D_GLIBCXX_USE_C99_MATH.
The problem is that __gnu_cxx::isnan<>() calls __gnu_cxx::__capture_isnan<>(),
which in turn recursively calls __gnu_cxx::isnan<>().
Indeed, FreeBSD's math.h contains the following snippet:
#define isnan(x) \
((sizeof (x) == sizeof (float)) ? isnanf(x) \
: (sizeof (x) == sizeof (double)) ? isnan(x) \
: __isnanl(x))
So, isnan() is both a macro and a function taking a double. If my
understanding is correct, __capture_isnan() calls __gnu_cxx::isnan() instead of
::isnan().
I am well aware that std::isnan() is probably not strictly standard C++ (since
isnan is new in C99), but I'd consider it a quality of implementation issue to
have it working if it is available.
Environment:
System: FreeBSD lorenzdesktop 5.3-RELEASE-p1 FreeBSD 5.3-RELEASE-p1 #3: Sat Dec 11 12:45:33 CET 2004 lorinder@lorenzdesktop:/usr/obj/usr/src/sys/MYKERNEL i386
FreeBSD 5.3, i386 (athlon-xp), system libc, and libstdc++.
host: i386-unknown-freebsd5.3
build: i386-unknown-freebsd5.3
target: i386-unknown-freebsd5.3
configured with: ../gcc/configure --enable-languages=c,c++,objc --disable-shared --program-suffix=-exp
How-To-Repeat:
Compile the aforementioned testprogram on FreeBSD 5.3.
------- Additional Comments From lminder at gmx dot net 2005-01-07 23:06 -------
Fix:
A possibility which fixes the problem for me is to define std::isnan<>() and
friends directly in std:: instead of definining them in __gnu_cxx:: and then
"importing" them to std::.
(On the other hand, there is probably a reason why things aren't done that way
to begin with.)
Below a hack to <cmath> which fixes the problem for me. (I haven't run the test
suite over it or anything, so this might well break other stuff).
--- /usr/include/c++/3.4/cmath.orig Fri Oct 29 03:08:48 2004
+++ /usr/include/c++/3.4/cmath Fri Jan 7 04:35:22 2005
@@ -515,61 +515,64 @@
#if _GLIBCXX_USE_C99_MATH
#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
-namespace __gnu_cxx
+namespace std
{
template<typename _Tp>
int
- fpclassify(_Tp __f) { return __capture_fpclassify(__f); }
+ fpclassify(_Tp __f) { return __gnu_cxx::__capture_fpclassify(__f); }
template<typename _Tp>
int
- isfinite(_Tp __f) { return __capture_isfinite(__f); }
+ isfinite(_Tp __f) { return __gnu_cxx::__capture_isfinite(__f); }
template<typename _Tp>
int
- isinf(_Tp __f) { return __capture_isinf(__f); }
+ isinf(_Tp __f) { return __gnu_cxx::__capture_isinf(__f); }
template<typename _Tp>
int
- isnan(_Tp __f) { return __capture_isnan(__f); }
+ isnan(_Tp __f) { return __gnu_cxx::__capture_isnan(__f); }
template<typename _Tp>
int
- isnormal(_Tp __f) { return __capture_isnormal(__f); }
+ isnormal(_Tp __f) { return __gnu_cxx::__capture_isnormal(__f); }
template<typename _Tp>
int
- signbit(_Tp __f) { return __capture_signbit(__f); }
+ signbit(_Tp __f) { return __gnu_cxx::__capture_signbit(__f); }
template<typename _Tp>
int
- isgreater(_Tp __f1, _Tp __f2) { return __capture_isgreater(__f1, __f2); }
+ isgreater(_Tp __f1, _Tp __f2) {
+ return __gnu_cxx::__capture_isgreater(__f1, __f2); }
template<typename _Tp>
int
isgreaterequal(_Tp __f1, _Tp __f2)
- { return __capture_isgreaterequal(__f1, __f2); }
+ { return __gnu_cxx::__capture_isgreaterequal(__f1, __f2); }
template<typename _Tp>
int
- isless(_Tp __f1, _Tp __f2) { return __capture_isless(__f1, __f2); }
+ isless(_Tp __f1, _Tp __f2) { return
+ __gnu_cxx::__capture_isless(__f1, __f2); }
template<typename _Tp>
int
islessequal(_Tp __f1, _Tp __f2)
- { return __capture_islessequal(__f1, __f2); }
+ { return __gnu_cxx::__capture_islessequal(__f1, __f2); }
template<typename _Tp>
int
islessgreater(_Tp __f1, _Tp __f2)
- { return __capture_islessgreater(__f1, __f2); }
+ { return __gnu_cxx::__capture_islessgreater(__f1, __f2); }
template<typename _Tp>
int
isunordered(_Tp __f1, _Tp __f2)
- { return __capture_isunordered(__f1, __f2); }
+ { return __gnu_cxx::__capture_isunordered(__f1, __f2); }
}
+/*
namespace std
{
using __gnu_cxx::fpclassify;
@@ -585,6 +588,7 @@
using __gnu_cxx::islessgreater;
using __gnu_cxx::isunordered;
}
+*/
#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */
#endif
--
Summary: std::isnan<>() is broken on FreeBSD
Product: gcc
Version: 4.0.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: lminder at gmx dot net
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i386-unknown-freebsd5.3
GCC host triplet: i386-unknown-freebsd5.3
GCC target triplet: i386-unknown-freebsd5.3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19322
More information about the Gcc-bugs
mailing list