Problem building CVS version on OS X

Tom Loredo <loredo@...296...> writes:

http://www.ssl.berkeley.edu/pipermail/boinc_dev/2004-October/000529.html

It involves including math.h and defining a prototype for isnan
explicitly.

I suppose that would work, but then you will take a slight performance
hit when calling isnan. It's probably not too bad; depends on how
often it gets called.

Apple's cmath include file (my version of it, anyway, in
/usr/include/gcc/darwin/3.3/c++/) first defines a template function
that expands the macro, then undefines the macro and makes the
function available in the standard namespace (I've omitted a lot of
stuff here):

  namespace __gnu_cxx
  {
    template<typename _Tp>
      int
      __capture_isnan(_Tp __f) { return isnan(__f); }
  }
  #undef isnan
  namespace __gnu_cxx
  {
    template<typename _Tp>
      int
      isnan(_Tp __f) { return __capture_isnan(__f); }
  }

  namespace std
  {
    using __gnu_cxx::isnan;
  }

So this ensures that when you call std::isnan, it is expanded at
compile-time to a call to __capture_isnan, which in turn is expanded
to the original isnan macro.

It also probably means that including math.h before cmath will have no
effect, since cmath will #undef the isnan macro. Including math.h
after cmath will also have no effect, since it is guarded with #ifndef
__MATH_H__.

The solution at the URL you mentioned adds a prototype for the isnan
function, which is included in the math library. I think it only
handles doubles, not floats or long doubles (and I have absolutely no
idea whether casting a float NaN to double works), and a function call
causes a minor performance hit. Other than that, I suppose that's
fine.

Somehow your cmath is failing to define isnan. At least in my version,
the definitions in __gnu_cxx (but not the #undef!) are conditioned on

  #if _GLIBCPP_USE_C99

Googling with that macro and isnan shows that a lot of other people
have been having similar problems. Another attempt at a solution is at
http://tolstoy.newcastle.edu.au/~rking/R/devel/05/01/1861.html
Another possibly relevant page is
http://lists.apple.com/archives/Xcode-users/2005/Feb/msg00238.html

Apparently, the upshot is that isnan is a C99 feature and C++ does not
incorporate C99. Perhaps the feature has been added anyway in some
version of gcc 3.3 between yours and mine.

···

--
Jouni

Referring to this:

/ #include <math.h>

/32a34,37

/ extern "C" {

/>/ int isnan(double);
/>/ }

/Jouni K Seppanen wrote:

I suppose that would work, but then you will take a slight performance
hit when calling isnan. It's probably not too bad; depends on how
often it gets called.

The code that makes use of isnan is not called enough to be worried about a minor speed hit.

Apparently, the upshot is that isnan is a C99 feature and C++ does not
incorporate C99.

So, does that mean the above should work on most C++ compilers? (Do they implement C99 mode when in extern "C" mode?) If so, I'm all for that approach as abandoning the isnan64 macro I borrowed from numarray. I'd rather take the minor speed hit than have all that intricate C coding currently in the MPL_isnan.h file.