Subject: Re: [boost] [Review Request] Multiprecision Arithmetic Library
From: John Maddock (boost.regex_at_[hidden])
Date: 2012-04-05 03:59:16


>> I have struggled with this issue before. Maybe you
>> help me out.
>
> <snip>
>> The is_initialized flag (which is actually a kind of manual
>> "guard-variable")
>> should be set to true *after* initializing the representartion of pi.
>
> Ahhhh! But you got it right. Excellent.
> You initialize "b" after initializing the representation
> of pi, ln2, etc.
>
> I think that's looking OK for threads.

Actually no, that code *on it's own* is most definitely not thread safe.
Anywhere you have a function scope:

static const UDT my_object.

where UDT is not a POD, then initialization of my_object is subject to race
conditions (in C++03 anyway, C++11 and recent GCC versions get this right I
believe).

What's more if you try to fix the race condition using the "double checked
looking idiom", it's still not thread safe, you actually do have to grab a
mutex with every call to the function :-(

However, there's a trick I stole from Boost.Pool employed here, in the:

   constant_initializer<T, &get_constant_e<T> >::do_nothing();

Which ultimately calls the global object
constant_initialized<>::initializer::do_nothing() - purely to make sure that
that object is instantiated. And once it is instantiated, because it's a
global object it gets constructed before main(), and it's constructor makes
a call to get_constant_e<T>, thus initializing our constant, also before
main is called. Tricky, and convoluted, but effective!

HTH, John.