This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #122788] broken nan on win32
authorJarkko Hietaniemi <jhi@iki.fi>
Tue, 16 Sep 2014 21:20:54 +0000 (17:20 -0400)
committerJarkko Hietaniemi <jhi@iki.fi>
Tue, 16 Sep 2014 23:18:38 +0000 (19:18 -0400)
Apparently VS 2003 smartly optimizes (HUGE_VAL-HUGE_VAL) into zero,
so using that for NaN was quite a disaster.  Let instead Win32 fall
thru to the __PL_nan_u option.  (HUGE_VAL for Inf is fine.)

perl.h

diff --git a/perl.h b/perl.h
index 0bcbd08..82e604d 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -4145,9 +4145,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
@@ -4244,6 +4243,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)