[R] ISNAN() broken? in ver 2.x on MacOS X

Bill Northcott w.northcott at unsw.edu.au
Tue Jan 4 12:40:23 CET 2005


I was attempting builds using both the standalone library including 
only Rmath.h and the using the installed R using R.h as well.  
Basically I have the following in relevant programs:
#ifndef MATHLIB_STANDALONE
#include <R.h>
#endif /* MATHLIB_STANDALONE */

As far as I can see, the only difference is the version of R.  ISNAN() 
will always fail on MacOS X with R 2.0.x whereas it might work with a 
standalone v1.9.x libRmath.

I tried reordering the headers but without any success.

The minimal test case to illustrate the problem is:
#include <iostream>
#include <math.h>
isnan(x)

Preprocess this on MacOS X and the isnan(x) will be unchanged which is 
wrong as isnan(x) is a macro in math.h.  Remove the iostream include 
and it will work properly.

In short there is a problem with the IEEE macros and C++ on MacOS X.

Bill Northcott
On 04/01/2005, at 7:09 PM, Prof Brian Ripley wrote:
> This is a good example of why it is necessary to include all the 
> pertinent details (and I know that demands knowing the answer, but 
> using standalone Rmath.h is *not* `an extension').  That you were 
> using C++ was also pertinent.
>
> I don't think you should be using <R.h> if you are building against
> standalone libRmath.
>
>>
>> I finally found it.  The culprit is
>> #include <iostream>
>> which is used in our real code
>>
>> If I preprocess the following code then the substitution is ISNAN() 
>> --> (isnan(x)!=0)
>> #include <iostream>
>> #include <R.h>
>> #include <Rmath.h>
>> ISNAN(x);
>>
>> Removing the #include <iostream> the substitution becomes
>> ISNAN(x)   --> (( ( sizeof ( x ) == sizeof(double) ) ? __isnand ( x ) 
>> : ( sizeof ( x ) == sizeof( float) ) ? __isnanf ( x ) : __isnan ( x ) 
>> )!=0)
>> which is correct.
>>
>> This behaviour is the same with both gcc 3.3 and pre-release gcc 4.0 
>> on MacOS X 10.3.7.
>>
>> Is this a bug we should report to someone such the gcc maintainers?
>
> You might want to swap the order of inclusion of headers.  Using C 
> headers in a C++ program is always slightly dodgy.
>
>
>> Bill Northcott
>> On 04/01/2005, at 1:48 PM, Thomas Lumley wrote:
>>>> In R 1.9.1 Arith.h and Rmath.h contained code like
>>>> #ifdef IEEE_754
>>>> # define ISNAN(x) (isnan(x)!=0)
>>>> #else
>>>> # define ISNAN(x)      R_IsNaNorNA(x)
>>>> #endif
>>>> #define R_FINITE(x)    R_finite(x)
>>>> int R_IsNaNorNA(double);
>>> Although you have clearly gone to some effort to diagnose this, I 
>>> think your diagnosis is incorrect.
>>> 1) In R 1.9.1 IEEE_754 was #defined on OS X, so we would already 
>>> have had
>>>   #define ISNAN(x) (isnan(x)!=0)
>>> 2) The gcc C preprocessor documentation says
>>>   "When the preprocessor expands a macro name, the macro's expansion
>>>   replaces the macro invocation, then the expansion is examined for 
>>> more
>>>   macros to expand. For example,
>>>      #define TABLESIZE BUFSIZE
>>>      #define BUFSIZE 1024
>>>      TABLESIZE
>>>           ==> BUFSIZE
>>>           ==> 1024
>>>   TABLESIZE is expanded first to produce BUFSIZE, then that macro is
>>>   expanded to produce the final result, 1024."
>>> and while I haven't been able to find anything definitive about the 
>>> ANSI standard, the gcc documentation usually flags extensions fairly 
>>> well and in any case you are presumably using gcc (though you don't 
>>> say explicitly).
>>> A work-around would be to use isnan() rather than ISNAN().
>
> -- 
> Brian D. Ripley,                  ripley at stats.ox.ac.uk
> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
> University of Oxford,             Tel:  +44 1865 272861 (self)
> 1 South Parks Road,                     +44 1865 272866 (PA)
> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>




More information about the R-help mailing list