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" {