(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 [EMAIL PROTECTED]:/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