This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
infnan: more tests.
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 8d817ab..8e81724 100644 (file)
--- a/perl.h
+++ b/perl.h
 #   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
 
@@ -1843,23 +1850,6 @@ typedef NVTYPE NV;
 #   include <ieeefp.h>
 #endif
 
-/* We need Perl_isfinitel (ends with ell) (if available) even when
- * not USE_LONG_DOUBLE because the printf code (sv_catpvfn_flags)
- * needs that. */
-#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)
-#        define Perl_isfinitel(x) isfinite(x)
-#    elif defined(HAS_ISFINITEL)
-#        define Perl_isfinitel(x) isfinitel(x)
-#    elif defined(HAS_FINITEL)
-#       define Perl_isfinitel(x) finitel(x)
-#    elif defined(LDBL_MAX)
-#       define Perl_isfinitel(x) ((x) <= LDBL_MAX && (x) >= -LDBL_MAX)
-#   endif
-#endif
-
 #ifdef USE_LONG_DOUBLE
 #   ifdef I_SUNMATH
 #       include <sunmath.h>
@@ -1962,7 +1952,7 @@ EXTERN_C long double modfl(long double, long double *);
 #           define Perl_isinf(x) ((x) > LDBL_MAX || (x) < -LDBL_MAX)
 #       endif
 #   endif
-#   ifdef Perl_isfinitel
+#   ifndef Perl_isfinite
 #       define Perl_isfinite(x) Perl_isfinitel(x)
 #   endif
 #else
@@ -2042,8 +2032,6 @@ EXTERN_C long double modfl(long double, long double *);
 #       define Perl_isfinite(x) isfinite(x)
 #     elif defined(HAS_FINITE)
 #       define Perl_isfinite(x) finite(x)
-#     elif defined(DBL_MAX)
-#       define Perl_isfinite(x) ((x) <= DBL_MAX && (x) >= -DBL_MAX)
 #     endif
 #   endif
 #endif
@@ -2300,13 +2288,15 @@ int isnan(double d);
 
 #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
@@ -2317,6 +2307,25 @@ int isnan(double d);
 #   endif
 #endif
 
+/* We need Perl_isfinitel (ends with ell) (if available) even when
+ * not USE_LONG_DOUBLE because the printf code (sv_catpvfn_flags)
+ * needs that. */
+#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(HAS_ISFINITE) && defined(isfinite) && defined(HAS_C99)
+#        define Perl_isfinitel(x) isfinite(x)
+#    elif defined(HAS_ISFINITEL)
+#        define Perl_isfinitel(x) isfinitel(x)
+#    elif defined(HAS_FINITEL)
+#        define Perl_isfinitel(x) finitel(x)
+#    elif defined(HAS_INFL) && defined(HAS_NANL)
+#        define Perl_isfinitel(x) !(isinfl(x)||isnanl(x))
+#    else
+#        define Perl_isfinitel(x) ((x) * 0 == 0)  /* See Perl_isfinite. */
+#    endif
+#endif
+
 /* The default is to use Perl's own atof() implementation (in numeric.c).
  * Usually that is the one to use but for some platforms (e.g. UNICOS)
  * it is however best to use the native implementation of atof.
@@ -4133,9 +4142,8 @@ END_EXTERN_C
 #  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
@@ -4232,6 +4240,9 @@ static const union { unsigned int __i; float __f; } __PL_nan_u =
 #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)