From 022f958fc0299938ac00f4fe8b604f025e552623 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 20:01:23 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_UP) 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/univpoly.h | 9 ++++++++- src/polynomial/elem/cl_UP.cc | 25 ++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/cln/univpoly.h b/include/cln/univpoly.h index f7c655d..8915254 100644 --- a/include/cln/univpoly.h +++ b/include/cln/univpoly.h @@ -352,7 +352,14 @@ extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r); // Lookup or create a univariate polynomial ring with a named variable over r. extern const cl_univpoly_ring find_univpoly_ring (const cl_ring& r, const cl_symbol& varname); -CL_REQUIRE(cl_UP) +class cl_UP_init_helper +{ + static int count; +public: + cl_UP_init_helper(); + ~cl_UP_init_helper(); +}; +static cl_UP_init_helper cl_UP_init_helper_instance; // Operations on polynomials. diff --git a/src/polynomial/elem/cl_UP.cc b/src/polynomial/elem/cl_UP.cc index 967e385..b3a527f 100644 --- a/src/polynomial/elem/cl_UP.cc +++ b/src/polynomial/elem/cl_UP.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_UP) - // Specification. #define CL_GV_NO_RANGECHECKS #define CL_SV_NO_RANGECHECKS @@ -43,10 +41,24 @@ static void cl_univpoly_ring_destructor (cl_heap* pointer) (*(cl_heap_univpoly_ring*)pointer).~cl_heap_univpoly_ring(); } -cl_class cl_class_univpoly_ring = { - cl_univpoly_ring_destructor, - cl_class_flags_univpoly_ring -}; +cl_class cl_class_univpoly_ring; + +int cl_UP_init_helper::count = 0; + +cl_UP_init_helper::cl_UP_init_helper() +{ + if (count++ == 0) { + cl_class_univpoly_ring.destruct = cl_univpoly_ring_destructor; + cl_class_univpoly_ring.flags = cl_class_flags_univpoly_ring; + } +} + +cl_UP_init_helper::~cl_UP_init_helper() +{ + if (--count == 0) { + // nothing to clean up + } +} cl_heap_univpoly_ring::cl_heap_univpoly_ring (const cl_ring& r, cl_univpoly_setops* setopv, cl_univpoly_addops* addopv, cl_univpoly_mulops* mulopv, cl_univpoly_modulops* modulopv, cl_univpoly_polyops* polyopv) : setops (setopv), addops (addopv), mulops (mulopv), modulops (modulopv), polyops (polyopv), @@ -74,4 +86,3 @@ cl_heap_univpoly_ring* cl_make_univpoly_ring (const cl_ring& r) } // namespace cln -CL_PROVIDE_END(cl_UP)