From 74ff6e93384732805503f941f3e33fff0a6de0ff Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 15:46:16 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_FF_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/ffloat_class.h | 9 ++++++++- src/float/ffloat/elem/cl_FF_globals.cc | 27 ++++++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/include/cln/ffloat_class.h b/include/cln/ffloat_class.h index f53b7fd..b1c54e2 100644 --- a/include/cln/ffloat_class.h +++ b/include/cln/ffloat_class.h @@ -62,7 +62,14 @@ inline cl_FF::operator struct cl_heap_ffloat * () const extern const cl_FF cl_FF_0; inline cl_FF::cl_FF () : cl_F ((cl_private_thing) (struct cl_heap_ffloat *) cl_FF_0) {} -CL_REQUIRE(cl_FF_globals) +class cl_FF_globals_init_helper +{ + static int count; +public: + cl_FF_globals_init_helper(); + ~cl_FF_globals_init_helper(); +}; +static cl_FF_globals_init_helper cl_FF_globals_init_helper_instance; #if 0 // see cl_FF.h inline cl_FF::cl_FF (struct cl_heap_ffloat * ptr) : cl_F ((cl_private_thing) ptr) {} diff --git a/src/float/ffloat/elem/cl_FF_globals.cc b/src/float/ffloat/elem/cl_FF_globals.cc index 68c7eeb..7c98cf6 100644 --- a/src/float/ffloat/elem/cl_FF_globals.cc +++ b/src/float/ffloat/elem/cl_FF_globals.cc @@ -3,9 +3,8 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_FF_globals) - // Specification. +#include "cln/ffloat_class.h" #include "cl_FF.h" @@ -15,14 +14,30 @@ namespace cln { #if !defined(CL_WIDE_POINTERS) -const cl_FF cl_FF_0 = allocate_ffloat(0); // 0.0f0 +const cl_FF cl_FF_0 = cl_FF_0; // 0.0f0 + +const cl_FF cl_FF_1 = cl_FF_1; // 1.0f0 + +const cl_FF cl_FF_minus1 = cl_FF_minus1; // -1.0f0 -const cl_FF cl_FF_1 = encode_FF(0,1,bit(FF_mant_len)); // 1.0f0 +int cl_FF_globals_init_helper::count = 0; -const cl_FF cl_FF_minus1 = encode_FF(-1,1,bit(FF_mant_len)); // -1.0f0 +cl_FF_globals_init_helper::cl_FF_globals_init_helper() +{ + if (count++ == 0) { + new ((void *)&cl_FF_0) cl_FF(allocate_ffloat(0)); // 0.0f0 + new ((void *)&cl_FF_1) cl_FF(encode_FF(0,1,bit(FF_mant_len))); // 1.0f0 + new ((void *)&cl_FF_minus1) cl_FF(encode_FF(-1,1,bit(FF_mant_len))); // -1.0f0 + } +} +cl_FF_globals_init_helper::~cl_FF_globals_init_helper() +{ + if (--count == 0) { + // Nothing to clean up + } +} #endif } // namespace cln -CL_PROVIDE_END(cl_FF_globals)