]> www.ginac.de Git - cln.git/commitdiff
Replace CL_REQUIRE/CL_PROVIDE(cl_LF_globals) with portable code.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Thu, 21 Aug 2008 11:46:29 +0000 (15:46 +0400)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Wed, 27 Aug 2008 04:41:05 +0000 (08:41 +0400)
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
src/float/lfloat/elem/cl_LF_globals.cc

index cd34668bb0149b3fbd773706060347f5f03de57f..8c0087894849b9517c287a5b5a94546ae51a5ed8 100644 (file)
@@ -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) {}
index 9284a188cfee813ff81d1dd1da0b240fd752430f..47c754e80947388cec0500d8c6675e4a1c3097dc 100644 (file)
@@ -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)