From bug-request at octave dot org Thu Dec 16 13:50:10 2004 Subject: signbit on linux/gcc 3.2+ From: Orion Poplawski To: bug at octave dot org Date: Thu, 16 Dec 2004 13:25:30 -0600 Octave uses the autoconf mechanism AC_CHECK_FUNCS() to look for signbit. This doesn't work for linux with gcc 3.2+ because signbit is a macro in , and is only exposed if _GNU_SOURCE, _ISOC99_SOURCE, _ISOC9X_SOURCE, or __STDC_VERSION__ >= 199901L. To make things more complicated, in c++ if is included, the macro is turned off and it is replaced with the std::signbit() function. In liboctave/lo-ieee.h, lo_ieee_signbit it declared as follows: /* In the following definitions, only check x < 0 explicitly to avoid a function call when it looks like signbit or copysign are actually functions. */ #if defined (signbit) # define lo_ieee_signbit(x) signbit (x) #elif defined (HAVE_SIGNBIT) # if defined (__MINGW32__) extern int signbit (double); # endif # define lo_ieee_signbit(x) (x < 0 || signbit (x)) #elif defined (copysign) # define lo_ieee_signbit(x) (copysign (1.0, x) < 0) #elif defined (HAVE_COPYSIGN) # define lo_ieee_signbit(x) (x < 0 || copysign (1.0, x) < 0) #else # define lo_ieee_signbit(x) 0 #endif So, you end up with lo_ieee_signbit(x) defined as 0. Which seems like a pretty bad thing, and it is not advertised as such (no error is generated). My proposed fix is as follows: - Change configure.in to check for the signbit *declaration*: --- configure.in.orig 2004-12-15 17:26:11.082647280 -0700 +++ configure.in 2004-12-15 17:26:55.482848586 -0700 at @ -1152,7 +1152,8 @@ AC_DEFINE(HAVE_ISNAN, 1, [Define if you have isnan().]) ;; *) - AC_CHECK_FUNCS(finite isnan isinf copysign signbit) + AC_CHECK_FUNCS(finite isnan isinf copysign) + AC_CHECK_DECLS(signbit,,,[#include ]) ;; esac --- liboctave/lo-ieee.h.orig 2003-09-05 10:55:42.000000000 -0600 +++ liboctave/lo-ieee.h 2004-12-16 11:29:10.697873801 -0700 at @ -23,8 +23,14 @@ #if !defined (octave_liboctave_ieee_h) #define octave_liboctave_ieee_h 1 +#include + #ifdef __cplusplus +/* Use standard c++ signbit */ +#include +using std::signbit; + extern "C" { #endif /* Octave's idea of infinity. */ at @ -72,7 +78,7 @@ #if defined (signbit) #define lo_ieee_signbit(x) signbit (x) -#elif defined (HAVE_SIGNBIT) +#elif defined (HAVE_DECL_SIGNBIT) #if defined (__MINGW32__) extern int signbit (double); #endif at @ -82,7 +88,7 @@ #elif defined (HAVE_COPYSIGN) #define lo_ieee_signbit(x) (x < 0 || copysign (1.0, x) < 0) #else -#define lo_ieee_signbit(x) 0 +#error "No signbit definition?!" #endif #ifdef __cplusplus - Somewhere someone would still need to define _GNU_SOURCE or _ISO_C99SOURCE or some such. Not sure how you want to handle this. I do it when I run configure, but it probably should be automatic. - This will flag an error rather than define lo_ieee_signbit(x) as zero. Of course, all this probably breaks other platforms. -- Orion Poplawski System Administrator 303-415-9701 x222 Colorado Research Associates/NWRA FAX: 303-415-9702 3380 Mitchell Lane, Boulder CO 80301 http://www.co-ra.com ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------