From 311046b5c734f0df38db6953e1f3911d1229bf34 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 15:54:46 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_R_ring) 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/real_ring.h | 11 ++++++++++- include/cln/univpoly_real.h | 2 -- src/real/ring/cl_R_ring.cc | 35 +++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/include/cln/real_ring.h b/include/cln/real_ring.h index 6baeb9f..4ee2c28 100644 --- a/include/cln/real_ring.h +++ b/include/cln/real_ring.h @@ -11,7 +11,16 @@ namespace cln { typedef cl_specialized_number_ring cl_real_ring; extern const cl_real_ring cl_R_ring; // math. R extern cl_class cl_class_real_ring; -//CL_REQUIRE(cl_R_ring) + +class cl_R_ring_init_helper +{ + static int count; +public: + cl_R_ring_init_helper(); + ~cl_R_ring_init_helper(); +}; + +static cl_R_ring_init_helper cl_R_ring_init_helper_instance; } // namespace cln diff --git a/include/cln/univpoly_real.h b/include/cln/univpoly_real.h index 59d302c..7338e94 100644 --- a/include/cln/univpoly_real.h +++ b/include/cln/univpoly_real.h @@ -223,8 +223,6 @@ inline const cl_UP_R deriv (const cl_UP_R& x) #endif -CL_REQUIRE(cl_R_ring) - } // namespace cln #endif /* _CL_UNIVPOLY_REAL_H */ diff --git a/src/real/ring/cl_R_ring.cc b/src/real/ring/cl_R_ring.cc index 5350bdd..7dbdeaf 100644 --- a/src/real/ring/cl_R_ring.cc +++ b/src/real/ring/cl_R_ring.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_R_ring) - // Specification. #include "cln/real_ring.h" @@ -145,19 +143,36 @@ static void cl_real_ring_dprint (cl_heap* pointer) fprint(cl_debugout, "(cl_real_ring) cl_R_ring"); } -cl_class cl_class_real_ring = { - cl_real_ring_destructor, - cl_class_flags_number_ring, - cl_real_ring_dprint -}; +static cl_heap_real_ring* cl_heap_real_ring_instance; +cl_class cl_class_real_ring; // Constructor. template <> inline cl_real_ring::cl_specialized_number_ring () - : cl_number_ring (new cl_heap_real_ring()) {} + : cl_number_ring (cl_heap_real_ring_instance) {} + +const cl_real_ring cl_R_ring = cl_R_ring; + +int cl_R_ring_init_helper::count = 0; + +cl_R_ring_init_helper::cl_R_ring_init_helper() +{ + if (count++ == 0) { + cl_class_real_ring.destruct = cl_real_ring_destructor; + cl_class_real_ring.flags = cl_class_flags_number_ring; + cl_class_real_ring.dprint = cl_real_ring_dprint; + cl_heap_real_ring_instance = new cl_heap_real_ring(); + new((void *)&cl_R_ring) cl_real_ring(); + } +} + +cl_R_ring_init_helper::~cl_R_ring_init_helper() +{ + if (--count == 0) { + delete cl_heap_real_ring_instance; + } +} -const cl_real_ring cl_R_ring; } // namespace cln -CL_PROVIDE_END(cl_R_ring)