Martin Sebor wrote:
>
>Travis, while testing your updated patch, I wonder if it would be
>possible to quickly and easily fix STDCXX-509 even for MSVC in
>a binary compatible way by using #pragma init_seg to initialize
>the constants before any user-defined objects?
>
>http://msdn2.microsoft.com/en-us/library/7977wcck(VS.71).aspx
>http://msdn2.microsoft.com/en-us/library/7977wcck(VS.80).aspx
>
>Martin

Yes, I think this is okay. I've attached a patch that includes this
change. I also added a rather ugly macro to use to guard this stuff to
avoid repeating the crazy logic in multiple places.

Travis
Index: include/limits
===================================================================
--- include/limits      (revision 585243)
+++ include/limits      (working copy)
@@ -88,7 +88,8 @@
 
 _RWSTD_NAMESPACE (__rw) {
 
-#ifndef _RWSTD_NO_OBJECT_MANGLING
+#if    !defined(_RWSTD_NO_OBJECT_MANGLING)               \
+    && !defined(_RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX)
 
 extern "C" {
 
Index: include/rw/_config-msvc.h
===================================================================
--- include/rw/_config-msvc.h   (revision 585243)
+++ include/rw/_config-msvc.h   (working copy)
@@ -58,6 +58,10 @@
 
 #endif   // MSVC <= 6.0
 
+#if (_MSC_VER < 1400) && (_RWSTD_VER_MAJOR < 5)
+#  define _RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX
+#endif
+
    // disable "Same type qualifier used more than once"
 #  pragma warning (disable: 4114)
 
Index: src/limits_bits.cpp
===================================================================
--- src/limits_bits.cpp (revision 585243)
+++ src/limits_bits.cpp (working copy)
@@ -69,7 +69,8 @@
 
 #  endif   // _RWSTD_NO_LONG_DOUBLE
 
-#  ifndef _RWSTD_NO_OBJECT_MANGLING
+#  if    !defined(_RWSTD_NO_OBJECT_MANGLING)               \
+      && !defined(_RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX)
 
 extern "C" {
 
@@ -83,19 +84,25 @@
 // type. C linkage is (conditionally) used to defeat MSVC and other
 // "clever" compilers that mangle the type of objects into their names.
 
+#ifdef _RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX
+#  define _RWSTD_BITS_NAME(b) _RWSTD_PASTE (b,_bits)
+#else
+#  define _RWSTD_BITS_NAME(b) b
+#endif   // _RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX
+
 // infinity computed at config time
 _RWSTD_EXPORT extern const _DblBits
-__rw_dbl_infinity = { _RWSTD_DBL_INF_BITS };
+_RWSTD_BITS_NAME (__rw_dbl_infinity) = { _RWSTD_DBL_INF_BITS };
 
 
 _RWSTD_EXPORT extern const _FltBits
-__rw_flt_infinity = { _RWSTD_FLT_INF_BITS };
+_RWSTD_BITS_NAME (__rw_flt_infinity) = { _RWSTD_FLT_INF_BITS };
 
 
 #  ifndef _RWSTD_NO_LONG_DOUBLE
 
 _RWSTD_EXPORT extern const _LDblBits
-__rw_ldbl_infinity = { _RWSTD_LDBL_INF_BITS };
+_RWSTD_BITS_NAME (__rw_ldbl_infinity) = { _RWSTD_LDBL_INF_BITS };
 
 
 #  endif   // _RWSTD_NO_LONG_DOUBLE
@@ -103,17 +110,17 @@
 
 // quiet NaN computed at config time
 _RWSTD_EXPORT extern const _DblBits
-__rw_dbl_qNaN = { _RWSTD_DBL_QNAN_BITS };
+_RWSTD_BITS_NAME (__rw_dbl_qNaN) = { _RWSTD_DBL_QNAN_BITS };
 
 
 _RWSTD_EXPORT extern const _FltBits
-__rw_flt_qNaN = { _RWSTD_FLT_QNAN_BITS };
+_RWSTD_BITS_NAME (__rw_flt_qNaN) = { _RWSTD_FLT_QNAN_BITS };
 
 
 #  ifndef _RWSTD_NO_LONG_DOUBLE
 
 _RWSTD_EXPORT extern const _LDblBits
-__rw_ldbl_qNaN = { _RWSTD_LDBL_QNAN_BITS };
+_RWSTD_BITS_NAME (__rw_ldbl_qNaN) = { _RWSTD_LDBL_QNAN_BITS };
 
 
 #  endif   // _RWSTD_NO_LONG_DOUBLE
@@ -121,17 +128,17 @@
 
 // signaling NaN computed at config time
 _RWSTD_EXPORT extern const _DblBits
-__rw_dbl_sNaN = { _RWSTD_DBL_SNAN_BITS };
+_RWSTD_BITS_NAME (__rw_dbl_sNaN) = { _RWSTD_DBL_SNAN_BITS };
 
 
 _RWSTD_EXPORT extern const _FltBits
-__rw_flt_sNaN = { _RWSTD_FLT_SNAN_BITS };
+_RWSTD_BITS_NAME (__rw_flt_sNaN) = { _RWSTD_FLT_SNAN_BITS };
 
 
 #  ifndef _RWSTD_NO_LONG_DOUBLE
 
 _RWSTD_EXPORT extern const _LDblBits
-__rw_ldbl_sNaN = { _RWSTD_LDBL_SNAN_BITS };
+_RWSTD_BITS_NAME (__rw_ldbl_sNaN) = { _RWSTD_LDBL_SNAN_BITS };
 
 
 #  endif   // _RWSTD_NO_LONG_DOUBLE
@@ -139,38 +146,78 @@
 
 // denormalized minima computed at config time
 _RWSTD_EXPORT extern const _DblBits
-__rw_dbl_denorm_min = { _RWSTD_DBL_DENORM_MIN_BITS };
+_RWSTD_BITS_NAME (__rw_dbl_denorm_min) = { _RWSTD_DBL_DENORM_MIN_BITS };
 
 
 _RWSTD_EXPORT extern const _FltBits
-__rw_flt_denorm_min = { _RWSTD_FLT_DENORM_MIN_BITS };
+_RWSTD_BITS_NAME (__rw_flt_denorm_min) = { _RWSTD_FLT_DENORM_MIN_BITS };
 
 
 #  ifndef _RWSTD_NO_LONG_DOUBLE
 
 _RWSTD_EXPORT extern const _LDblBits
-__rw_ldbl_denorm_min = { _RWSTD_LDBL_DENORM_MIN_BITS };
+_RWSTD_BITS_NAME (__rw_ldbl_denorm_min) = { _RWSTD_LDBL_DENORM_MIN_BITS };
 
 
 #  endif   // _RWSTD_NO_LONG_DOUBLE
 
-}   // extern "C"/"C++"
 
+#  ifdef _RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX
 
-#else   // if defined (_RWSTD_NO_INFINITY)
+#pragma warning (push)
+#pragma warning (disable : 4073)
+// try to get these symbols initialized before dynamic
+// initialization time
+#pragma init_seg (lib)
+#pragma warning (pop)
 
+_RWSTD_EXPORT extern const float
+__rw_flt_infinity = _RWSTD_BITS_NAME (__rw_flt_infinity)._C_val;
 
-#  ifndef _RWSTD_NO_OBJECT_MANGLING
+_RWSTD_EXPORT extern const double
+__rw_dbl_infinity = _RWSTD_BITS_NAME (__rw_dbl_infinity)._C_val;
 
-extern "C" {
+_RWSTD_EXPORT extern const float
+__rw_flt_qNaN = _RWSTD_BITS_NAME (__rw_flt_qNaN)._C_val;
 
-#  else   // if defined (_RWSTD_NO_OBJECT_MANGLING)
+_RWSTD_EXPORT extern const double
+__rw_dbl_qNaN = _RWSTD_BITS_NAME (__rw_dbl_qNaN)._C_val;
 
-extern "C++" {
+_RWSTD_EXPORT extern const float
+__rw_flt_sNaN = _RWSTD_BITS_NAME (__rw_flt_sNaN)._C_val;
 
-#  endif   // _RWSTD_NO_OBJECT_MANGLING
+_RWSTD_EXPORT extern const double
+__rw_dbl_sNaN = _RWSTD_BITS_NAME (__rw_dbl_sNaN)._C_val;
 
+_RWSTD_EXPORT extern const float
+__rw_flt_denorm_min = _RWSTD_BITS_NAME (__rw_flt_denorm_min)._C_val;
 
+_RWSTD_EXPORT extern const double
+__rw_dbl_denorm_min = _RWSTD_BITS_NAME (__rw_dbl_denorm_min)._C_val;
+
+
+#    ifndef _RWSTD_NO_LONG_DOUBLE
+
+_RWSTD_EXPORT extern const long double
+__rw_ldbl_infinity = _RWSTD_BITS_NAME (__rw_ldbl_infinity)._C_val;
+
+_RWSTD_EXPORT extern const long double
+__rw_ldbl_qNaN = _RWSTD_BITS_NAME (__rw_ldbl_qNaN)._C_val;
+
+_RWSTD_EXPORT extern const long double
+__rw_ldbl_sNaN = _RWSTD_BITS_NAME (__rw_ldbl_sNaN)._C_val;
+
+_RWSTD_EXPORT extern const long double
+__rw_ldbl_denorm_min = _RWSTD_BITS_NAME (__rw_ldbl_denorm_min)._C_val;
+
+#    endif   // _RWSTD_NO_LONG_DOUBLE
+
+#  endif   // _RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX
+
+}   // extern "C"/"C++"
+
+#else   // if defined (_RWSTD_NO_INFINITY)
+
 // as the last resort compute values at dynamic initialization time
 _RWSTD_EXPORT extern const float __rw_flt_infinity =
 
@@ -243,8 +290,6 @@
 
 #  endif   // _RWSTD_NO_LONG_DOUBLE
 
-}   // extern "C"/"C++"
-
 #endif   // _RWSTD_NO_INFINITY
 
 
Index: src/num_get.cpp
===================================================================
--- src/num_get.cpp     (revision 585243)
+++ src/num_get.cpp     (working copy)
@@ -84,7 +84,8 @@
 typedef unsigned char UChar;
 
 
-#ifndef _RWSTD_NO_OBJECT_MANGLING
+#if    !defined(_RWSTD_NO_OBJECT_MANGLING)               \
+    && !defined(_RWSTD_MSVC7_STDCXX42_BINARY_COMPAT_FIX)
 
 extern "C" {
 

Reply via email to