Re: [Rd] Standalone Mathlib, C++ and ISNAN()
A review: The C++ math header undefines isnan, so if isnan is a macro, ISNAN() will not work in C++ code. C99 specifies that isnan is a macro, but in C90 compilers, where it is an extension, isnan is often a function (explaining why the issue didn't come up earlier). For example, isnan is a macro on my Mac laptop but a function on my Linux desktop. R-devel now defines ISNAN to call a function if used in C++ code. It still calls isnan in C code. -thomas Thomas Lumley Assoc. Professor, Biostatistics [EMAIL PROTECTED] University of Washington, Seattle __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On 06/01/2005, at 3:31 PM, John W. Eaton wrote: What I finally decided to do for Octave was to use a C language autoconf test for isnan, then provide a function declared extern C that is a wrapper around the C isnan function (if it exists). I also use this method for other functions that may be easier to call from C than directly from C++. Thanks for confirming my suspicions. As far as I can see that is just what R has done with the R_IsNaN function. I am just asking that it be included in the standalone Rmath library. Bill Northcott __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On Thu, 2005-01-06 at 08:29 +1100, Bill Northcott wrote: On 06/01/2005, at 6:53 AM, Thomas Lumley wrote: I believe (with a little Googling) the suggested C++ approach is to use std::isnan if cmath is included. I tried that too, but without any success. I even tried __gnu_cxx::isnan. It was suggested by one of the gcc people, but I could find no documentation about it. The ISO C++ docs do not include isnan as a symbol provided by cmath within the std namespace. I looked at the gcc source code and could see no reason why it should work. I think the workaround is supposed to look like this: #define _GLIBCPP_USE_C99 1 #include cmath #undef _GLIBCPP_USE_C99 #include iostream using __gnu_cxx::isnan; I don't know whether this solves the problem on MacOs X but it is valid on Linux. But do you really want to write code that is specific to gcc? I don't. Martyn __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On Wed, 5 Jan 2005, Bill Northcott wrote: If building against a full R library, one might possible use R_IsNaN instead but this function is not included in libRmath v2.0 and the function R_IsNaNorNA which was used in libRmath v1.9 no longer exists Yes, but in your standalone C or C++ code you can just use isnan() from math.h directly. The reason that R doesn't do that is twofold. In the past we tried to support computers that didn't use IEEE 754 arithmetic, which meant that isnan might not exist. Also, IIRC we found that isnan() doesn't use 1 for TRUE on all platforms -- sometimes it uses -1 or something else -- and code had assumed 1. That's why the strange-looking isnan(x)!=0 is there. You shouldn't have either of these problems in your C++ code, so it would be much easier to just use isnan(x) directly. The only complication would be distinguishing NA from other NaNs, but you won't have to do that in standalone C++ code. It would be worth noting somewhere that ISNAN breaks when some C++ headers are included on Mac OS X, and I will do that. -thomas __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On 06/01/2005, at 3:09 AM, Thomas Lumley wrote: If building against a full R library, one might possible use R_IsNaN instead but this function is not included in libRmath v2.0 and the function R_IsNaNorNA which was used in libRmath v1.9 no longer exists Yes, but in your standalone C or C++ code you can just use isnan() from math.h directly. As I explained in the last message: In R2.0 ISNAN() is defined using isnan thus (isnan(x)!=0). isnan() is in math.h and this works perfectly for C code. However, in C++ the header cmath (included by iostream and others) undefs isnan(). So on platforms for which isnan() is a macro, the code breaks at compile time with 'isnan() undeclared'. The reason that R doesn't do that is twofold. In the past we tried to support computers that didn't use IEEE 754 arithmetic, which meant that isnan might not exist. Also, IIRC we found that isnan() doesn't use 1 for TRUE on all platforms -- sometimes it uses -1 or something else -- and code had assumed 1. That's why the strange-looking isnan(x)!=0 is there. There is nothing strange about this. The spec for isnan says it is zero if and only if the object is not a nan. Any other value indicates a nan. It would be worth noting somewhere that ISNAN breaks when some C++ headers are included on Mac OS X, and I will do that. The point I am trying to make is that it is not just MacOS X. The g++ cmath header undefs isnan so it will break with gcc on any platform which has a macro for isnan. HP-UX is one. Also the C++ gurus insist that the ISO C++ standard requires cmath to zap the macros, which implies it will happen with other ISO compliant C++ compilers. There is a function R_IsNaN. I have not checked, but I presume it just calls isnan. This should work because it will not be zapped by the C++ headers, because it is in a different (C?) compilation unit. However, it is currently not part of the standalone Rmath.h/libRmath. It would be good if it could be included in the standalone build as was its predecessor R_IsNaNorNA. That way, we would have a workaround by using R_IsNaN. Bill Northcott __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On Thu, 6 Jan 2005, Bill Northcott wrote: As I explained in the last message: In R2.0 ISNAN() is defined using isnan thus (isnan(x)!=0). isnan() is in math.h and this works perfectly for C code. However, in C++ the header cmath (included by iostream and others) undefs isnan(). So on platforms for which isnan() is a macro, the code breaks at compile time with 'isnan() undeclared'. I believe (with a little Googling) the suggested C++ approach is to use std::isnan if cmath is included. -thomas Thomas Lumley Assoc. Professor, Biostatistics [EMAIL PROTECTED] University of Washington, Seattle __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On Thu, 6 Jan 2005, Bill Northcott wrote: On 06/01/2005, at 6:53 AM, Thomas Lumley wrote: I believe (with a little Googling) the suggested C++ approach is to use std::isnan if cmath is included. I tried that too, but without any success. I even tried __gnu_cxx::isnan. It was suggested by one of the gcc people, but I could find no documentation about it. The ISO C++ docs do not include isnan as a symbol provided by cmath within the std namespace. I looked at the gcc source code and could see no reason why it should work. Hmm. What *are* C++ programmers supposed to use to test for NaN, then? It might well not be anything in the ISO standard, just as it isn't in C89, but surely there is some prescribed way to do it. We don't want ISNAN to be a function unnecessarily in C, since it is used a lot and there is reportedly quite a bit of overhead to very simple functions on some processors. -thomas __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On 06/01/2005, at 9:12 AM, Thomas Lumley wrote: It was suggested by one of the gcc people, but I could find no documentation about it. The ISO C++ docs do not include isnan as a symbol provided by cmath within the std namespace. I looked at the gcc source code and could see no reason why it should work. Hmm. What *are* C++ programmers supposed to use to test for NaN, then? It might well not be anything in the ISO standard, just as it isn't in C89, but surely there is some prescribed way to do it. I asked the same question. So far I got no response. It seems the gods of C++ dictate that a C++ header must not pollute the default name space. cmath includes math.h so it must undefine everything in math.h which is not converted into the std namespace. I spent some time Googling on this and discovered a number of C++ maths packages that provided their own isnan type functions in the spirit of R_IsNaN. The fact that these functions were deemed useful by the package writers rather indicates to me that there is no way of doing it in a default ISO C++! isnan on MacOS X, and presumably other systems, is a macro so that it can work with floats, doubles and long doubles unlike R_IsNan which I understand will only work with doubles. There are actualy three underlying isnan functions in libSystem: __isnanf(float), __isnand(double) and __isnan(long double). We don't want ISNAN to be a function unnecessarily in C, since it is used a lot and there is reportedly quite a bit of overhead to very simple functions on some processors. I quite understand that and of course ISNAN works just great from C code. However, I do think it would be useful to provide a warning in the documentation about using ISNAN in C++ and include R_IsNaN in the standalone package as a workaround. The current state is that our code (JAGS), which used to work with R1.9, won't build against a standalone library on MacOS X and presumably other platforms with similar header structures. Bill Northcott PS All this just reinforces my long held belief that C++ is thoroughly undesirable, and if I want an OO extension of C, I will stick with Objective-C which just extends C in a minimalist way without stuffing it up. __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Standalone Mathlib, C++ and ISNAN()
On 6-Jan-2005, Bill Northcott [EMAIL PROTECTED] wrote: | On 06/01/2005, at 9:12 AM, Thomas Lumley wrote: | It was suggested by one of the gcc people, but I could find no | documentation about it. The ISO C++ docs do not include isnan as a | symbol provided by cmath within the std namespace. I looked at the | gcc source code and could see no reason why it should work. | | Hmm. What *are* C++ programmers supposed to use to test for NaN, | then? It might well not be anything in the ISO standard, just as it | isn't in C89, but surely there is some prescribed way to do it. | | I asked the same question. So far I got no response. What I finally decided to do for Octave was to use a C language autoconf test for isnan, then provide a function declared extern C that is a wrapper around the C isnan function (if it exists). I also use this method for other functions that may be easier to call from C than directly from C++. jwe -- www.octave.org | www.che.wisc.edu/~jwe | Peace would shock and awe me. __ R-devel@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-devel