# include "config.h"
#endif
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(_STDC_C99)
+/* NOTE 1: that with gcc -std=c89 the __STDC_VERSION__ is *not* defined
+ * because the __STDC_VERSION__ became a thing only with C90. Therefore,
+ * with gcc, HAS_C99 will never become true as long as we use -std=c89.
+
+ * NOTE 2: headers lie. Do not expect that if HAS_C99 gets to be true,
+ * all the C99 features are there and are correct. */
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ defined(_STDC_C99)
# define HAS_C99 1
#endif
# define Perl_isinf(x) ((x) > LDBL_MAX || (x) < -LDBL_MAX)
# endif
# endif
-# define Perl_isfinite(x) Perl_isfinitel(x)
+# ifndef Perl_isfinite
+# define Perl_isfinite(x) Perl_isfinitel(x)
+# endif
#else
# define NV_DIG DBL_DIG
# ifdef DBL_MANT_DIG
# define Perl_isfinite(x) isfinite(x)
# elif defined(HAS_FINITE)
# define Perl_isfinite(x) finite(x)
-# else
-/* For the infinities the multiplication returns nan,
- * for the nan the multiplication also returns nan,
- * for everything else (that is, finite) zero should be returned. */
-# define Perl_isfinite(x) ((x) * 0 == 0)
# endif
# endif
#endif
#ifndef Perl_isfinite
# if defined(HAS_ISFINITE) && !defined(isfinite)
-# define Perl_isfinite(x) isfinite((double)x)
+# define Perl_isfinite(x) isfinite((double)(x))
# elif defined(HAS_FINITE)
-# define Perl_isfinite(x) finite((double)x)
+# define Perl_isfinite(x) finite((double)(x))
# elif defined(Perl_fp_class_finite)
# define Perl_isfinite(x) Perl_fp_class_finite(x)
# else
-/* NaN*0 is NaN, [+-]Inf*0 is NaN, zero for anything else. */
+/* For the infinities the multiplication returns nan,
+ * for the nan the multiplication also returns nan,
+ * for everything else (that is, finite) zero should be returned. */
# define Perl_isfinite(x) (((x) * 0) == 0)
# endif
#endif
#if defined(HAS_LONG_DOUBLE) && !defined(Perl_isfinitel)
/* If isfinite() is a macro and looks like we have C99,
* we assume it's the type-aware C99 isfinite(). */
-# if defined(isfinite) && defined(HAS_C99)
+# if defined(HAS_ISFINITE) && defined(isfinite) && defined(HAS_C99)
# define Perl_isfinitel(x) isfinite(x)
# elif defined(HAS_ISFINITEL)
# define Perl_isfinitel(x) isfinitel(x)
# if !defined(NV_INF) && defined(HUGE_VAL)
# define NV_INF HUGE_VAL
# endif
-# ifndef NV_NAN
-# define NV_NAN (NV_INF-NV_INF)
-# endif
+/* For WIN32 the best NV_NAN is the __PL_nan_u trick, see below.
+ * There is no supported way of getting the NAN across all the crts. */
#endif
/* If you are thinking of using HUGE_VAL for infinity, or using
#if !defined(NV_NAN)
# define NV_NAN ((NV)0.0/0.0) /* Some compilers will warn. */
#endif
+/* Do NOT try doing NV_NAN based on NV_INF and trying (NV_INF-NV_INF).
+ * Though IEEE-754-logically correct, some compilers (like Visual C 2003)
+ * falsely misoptimize that to zero (x-x is zero, right?) */
#ifndef __cplusplus
# if !defined(WIN32) && !defined(VMS)