Skip to content

Commit 1744378

Browse files
author
tlumley
committed
make ISNAN call a function when in C++ code, in case isnan is a macro
git-svn-id: https://svn.r-project.org/R/trunk@32538 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 5f265d0 commit 1744378

File tree

5 files changed

+42
-3
lines changed

5 files changed

+42
-3
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ C-LEVEL FACILITIES
288288
o Added an onExit() function to graphics devices, to be executed
289289
upon user break if non-NULL.
290290

291+
o ISNAN now works even in C++ code that undefines the
292+
isnan macro.
293+
291294

292295
DEPRECATED & DEFUNCT
293296

src/include/R_ext/Arith.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,18 @@ int R_finite(double); /* True if none of NA, NaN, +/-Inf */
5151

5252
#define ISNA(x) R_IsNA(x)
5353
/* True for *both* NA and NaN.
54-
NOTE: some systems do not return 1 for TRUE. */
55-
#define ISNAN(x) (isnan(x)!=0)
54+
NOTE: some systems do not return 1 for TRUE.
55+
Also note that C++ math headers specifically undefine
56+
isnan if it is a macro (it is on OS X and in C99),
57+
hence the workaround. This code also appears in Rmath.h
58+
*/
59+
#ifdef __cplusplus
60+
int R_isnancpp(double); /* in arithmetic.c */
61+
# define ISNAN(x) R_isnancpp(x)
62+
#else
63+
# define ISNAN(x) (isnan(x)!=0)
64+
#endif
65+
5666
#ifdef HAVE_WORKING_ISFINITE
5767
/* isfinite is defined in <math.h> according to C99 */
5868
# define R_FINITE(x) isfinite(x)

src/include/Rmath.h0.in

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,15 @@ double gamma_cody(double);
581581
#ifdef MATHLIB_STANDALONE
582582
#ifndef MATHLIB_PRIVATE_H
583583

584-
# define ISNAN(x) (isnan(x)!=0)
584+
/* If isnan is a macro, as C99 specifies, the C++
585+
math header will undefine it. This happens on OS X */
586+
#ifdef __cplusplus
587+
int R_isnancpp(double); /* in mlutils.c */
588+
# define ISNAN(x) R_isnancpp(x)
589+
#else
590+
# define ISNAN(x) (isnan(x)!=0)
591+
#endif
592+
585593

586594
/* We don't have config information available to do anything else */
587595
#define R_FINITE(x) R_finite(x)

src/main/arithmetic.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ int R_IsNaN(double x)
131131
return 0;
132132
}
133133

134+
/* ISNAN uses isnan, which is undefined by C++ headers
135+
This workaround is called only when ISNAN() is used
136+
in a user code in a file with __cplusplus defined */
137+
138+
int R_isnancpp(double x)
139+
{
140+
return (isnan(x)!=0);
141+
}
142+
143+
134144
/* <FIXME> Simplify this mess. Not used inside R
135145
if isfinite works, and if finite works only in packages */
136146
int R_finite(double x)

src/nmath/mlutils.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ int R_finite(double x)
5454
#endif
5555
}
5656

57+
/* C++ math header undefines any isnan macro. This file
58+
doesn't get C++ headers and so is safe. */
59+
int R_isnancpp(double x)
60+
{
61+
return (isnan(x) != 0);
62+
63+
}
64+
5765
static double myfmod(double x1, double x2)
5866
{
5967
double q = x1 / x2;

0 commit comments

Comments
 (0)