Boost logo

Boost :

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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk