From ec25de1e6ca125433a2dbd7f6f85fb09c16c2743 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 15:55:45 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_RA_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/rational_ring.h | 10 +++++++++- include/cln/univpoly_rational.h | 2 -- src/rational/ring/cl_RA_ring.cc | 35 ++++++++++++++++++++++----------- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/cln/rational_ring.h b/include/cln/rational_ring.h index b6026cc..0a3dbfd 100644 --- a/include/cln/rational_ring.h +++ b/include/cln/rational_ring.h @@ -11,7 +11,15 @@ namespace cln { typedef cl_specialized_number_ring cl_rational_ring; extern const cl_rational_ring cl_RA_ring; // math. Q extern cl_class cl_class_rational_ring; -//CL_REQUIRE(cl_RA_ring) + +class cl_RA_ring_init_helper +{ + static int count; +public: + cl_RA_ring_init_helper(); + ~cl_RA_ring_init_helper(); +}; +static cl_RA_ring_init_helper cl_RA_ring_init_helper_instance; } // namespace cln diff --git a/include/cln/univpoly_rational.h b/include/cln/univpoly_rational.h index a1a6283..b958245 100644 --- a/include/cln/univpoly_rational.h +++ b/include/cln/univpoly_rational.h @@ -223,8 +223,6 @@ inline const cl_UP_RA deriv (const cl_UP_RA& x) #endif -CL_REQUIRE(cl_RA_ring) - // Returns the n-th Legendre polynomial (n >= 0). extern const cl_UP_RA legendre (sintL n); diff --git a/src/rational/ring/cl_RA_ring.cc b/src/rational/ring/cl_RA_ring.cc index f23035f..b42130f 100644 --- a/src/rational/ring/cl_RA_ring.cc +++ b/src/rational/ring/cl_RA_ring.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_RA_ring) - // Specification. #include "cln/rational_ring.h" @@ -143,19 +141,34 @@ static void cl_rational_ring_dprint (cl_heap* pointer) fprint(cl_debugout, "(cl_rational_ring) cl_RA_ring"); } -cl_class cl_class_rational_ring = { - cl_rational_ring_destructor, - cl_class_flags_number_ring, - cl_rational_ring_dprint -}; +cl_class cl_class_rational_ring; +static cl_heap_rational_ring* cl_heap_rational_ring_instance; // Constructor. template <> inline cl_rational_ring::cl_specialized_number_ring () - : cl_number_ring (new cl_heap_rational_ring()) {} + : cl_number_ring(cl_heap_rational_ring_instance) { } -const cl_rational_ring cl_RA_ring; +const cl_rational_ring cl_RA_ring = cl_RA_ring; -} // namespace cln +int cl_RA_ring_init_helper::count = 0; + +cl_RA_ring_init_helper::cl_RA_ring_init_helper() +{ + if (count++ == 0) { + cl_class_rational_ring.destruct = cl_rational_ring_destructor; + cl_class_rational_ring.flags = cl_class_flags_number_ring; + cl_class_rational_ring.dprint = cl_rational_ring_dprint; + cl_heap_rational_ring_instance = new cl_heap_rational_ring(); + new ((void *)&cl_RA_ring) cl_rational_ring(); + } +} -CL_PROVIDE_END(cl_RA_ring) +cl_RA_ring_init_helper::~cl_RA_ring_init_helper() +{ + if (--count == 0) { + delete cl_heap_rational_ring_instance; + } +} + +} // namespace cln