From bug-request at octave dot org Thu Dec 16 14:05:12 2004 Subject: signbit on linux/gcc 3.2+ From: "John W. Eaton" To: Orion Poplawski Cc: bug at octave dot org Date: Thu, 16 Dec 2004 15:06:23 -0500 On 16-Dec-2004, Orion Poplawski wrote: | 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. I didn't know there was a std::signbit function. If there was, then I don't think we would need all the checks for signbit appearing in various locations. | 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; | + I would prefer to avoid including in C++ code. | 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?!" It is probably bad to completely fail to compile if the system doesn't have a signbit function/macro. | Of course, all this probably breaks other platforms. Yes, for example: sun-45:9> cat foo.cc #include #include using std::signbit; #include int main (void) { std::cerr << signbit (-1.0) << std::endl; return 0; } sun-45:10> CC -V CC: Sun C++ 5.6 2004/07/15 sun-45:11> CC foo.cc "foo.cc", line 3: Error: signbit is not a member of std. "foo.cc", line 8: Error: The function "signbit" must have a prototype. 2 Error(s) detected. so I don't think I can accept this patch as it is. jwe ------------------------------------------------------------- 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 -------------------------------------------------------------