From ae1b7178f7294d2d97e9bbf6725a4e0454ab4919 Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Thu, 21 Aug 2008 15:55:11 +0400 Subject: [PATCH] Replace CL_REQUIRE/CL_PROVIDE(cl_I_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/integer_ring.h | 10 +++++++++- include/cln/univpoly_integer.h | 2 -- src/integer/ring/cl_I_ring.cc | 34 ++++++++++++++++++++++++---------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/cln/integer_ring.h b/include/cln/integer_ring.h index b8fcb29..cf9fae9 100644 --- a/include/cln/integer_ring.h +++ b/include/cln/integer_ring.h @@ -11,7 +11,15 @@ namespace cln { typedef cl_specialized_number_ring cl_integer_ring; extern const cl_integer_ring cl_I_ring; // math. Z extern cl_class cl_class_integer_ring; -//CL_REQUIRE(cl_I_ring) + +class cl_I_ring_init_helper +{ + static int count; +public: + cl_I_ring_init_helper(); + ~cl_I_ring_init_helper(); +}; +static cl_I_ring_init_helper cl_I_ring_init_helper_instance; } // namespace cln diff --git a/include/cln/univpoly_integer.h b/include/cln/univpoly_integer.h index 08b14b5..04235a4 100644 --- a/include/cln/univpoly_integer.h +++ b/include/cln/univpoly_integer.h @@ -218,8 +218,6 @@ inline const cl_UP_I deriv (const cl_UP_I& x) #endif -CL_REQUIRE(cl_I_ring) - // Returns the n-th Tchebychev polynomial (n >= 0). extern const cl_UP_I tschebychev (sintL n); diff --git a/src/integer/ring/cl_I_ring.cc b/src/integer/ring/cl_I_ring.cc index f7dc09a..e32acee 100644 --- a/src/integer/ring/cl_I_ring.cc +++ b/src/integer/ring/cl_I_ring.cc @@ -3,8 +3,6 @@ // General includes. #include "cl_sysdep.h" -CL_PROVIDE(cl_I_ring) - // Specification. #include "cln/integer_ring.h" @@ -143,19 +141,35 @@ static void cl_integer_ring_dprint (cl_heap* pointer) fprint(cl_debugout, "(cl_integer_ring) cl_I_ring"); } -cl_class cl_class_integer_ring = { - cl_integer_ring_destructor, - cl_class_flags_number_ring, - cl_integer_ring_dprint -}; +cl_class cl_class_integer_ring; +static cl_heap_integer_ring* cl_heap_integer_ring_instance; // Constructor. template <> inline cl_integer_ring::cl_specialized_number_ring () - : cl_number_ring (new cl_heap_integer_ring()) {} + : cl_number_ring(cl_heap_integer_ring_instance) {} + +const cl_integer_ring cl_I_ring = cl_I_ring; -const cl_integer_ring cl_I_ring; +int cl_I_ring_init_helper::count = 0; + +cl_I_ring_init_helper::cl_I_ring_init_helper() +{ + if (count++ == 0) { + cl_class_integer_ring.destruct = cl_integer_ring_destructor; + cl_class_integer_ring.flags = cl_class_flags_number_ring; + cl_class_integer_ring.dprint = cl_integer_ring_dprint; + cl_heap_integer_ring_instance = new cl_heap_integer_ring(); + new ((void *)&cl_I_ring) cl_integer_ring(); + } +} + +cl_I_ring_init_helper::~cl_I_ring_init_helper() +{ + if (--count == 0) { + delete cl_heap_integer_ring_instance; + } +} } // namespace cln -CL_PROVIDE_END(cl_I_ring)