From 7f619754e2a3d95a08c47d6e2312de8021ca2a5f Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 15:46:29 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_LF_globals) with portable code. The order of initialization of non-local objects in different compilation units is not specified in C++. Hence special care should be taken to avoid static initialization order fiasco. CLN solved the problem with some evil (GCC specific, and even GCC-version-specific) hack. Replace it with a technique similar to one used in STL to initialize std::cout and friends. --- include/cln/lfloat_class.h | 9 ++++++++- src/float/lfloat/elem/cl_LF_globals.cc | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/cln/lfloat_class.h b/include/cln/lfloat_class.h index cd34668..8c00878 100644 --- a/include/cln/lfloat_class.h +++ b/include/cln/lfloat_class.h @@ -53,7 +53,14 @@ inline cl_LF::operator struct cl_heap_lfloat * () const extern const cl_LF cl_LF_0; inline cl_LF::cl_LF () : cl_F ((cl_private_thing) (struct cl_heap_lfloat *) cl_LF_0) {} -CL_REQUIRE(cl_LF_globals) +class cl_LF_globals_init_helper +{ + static int count; +public: + cl_LF_globals_init_helper(); + ~cl_LF_globals_init_helper(); +}; +static cl_LF_globals_init_helper cl_LF_globals_init_helper_instance; #if 0 // see cl_LF_impl.h inline cl_LF::cl_LF (struct cl_heap_lfloat * ptr) : cl_F ((cl_private_thing) ptr) {} diff --git a/src/float/lfloat/elem/cl_LF_globals.cc b/src/float/lfloat/elem/cl_LF_globals.cc index 9284a18..47c754e 100644 --- a/src/float/lfloat/elem/cl_LF_globals.cc +++ b/src/float/lfloat/elem/cl_LF_globals.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_LF_globals) - // Specification. #include "cln/number.h" @@ -17,8 +15,21 @@ CL_PROVIDE(cl_LF_globals) namespace cln { // Only needed for the default constructor of cl_LF. -const cl_LF cl_LF_0 = encode_LF0(LF_minlen); // 0.0L0 +const cl_LF cl_LF_0 = cl_LF_0; // 0.0L0 + +int cl_LF_globals_init_helper::count = 0; +cl_LF_globals_init_helper::cl_LF_globals_init_helper() +{ + if (count++ == 0) + new ((void *)&cl_LF_0) cl_LF(encode_LF0(LF_minlen)); // 0.0L0 +} + +cl_LF_globals_init_helper::~cl_LF_globals_init_helper() +{ + if (--count == 0) { + // Nothing to clean up + } +} } // namespace cln -CL_PROVIDE_END(cl_LF_globals)