Boost logo

Boost :

From: John Maddock (john_at_[hidden])
Date: 2008-03-02 08:12:10

This came up in the floating point utilities review without a good answer,
but it's a general problem that's in need of one, so let me try again....

Suppose we have some global data that needs to be initialised, the obvious
answer is to use boost::call_once to ensure that it gets initialised exactly
once. But... what happens if this is used in a header to initialise some
static variable inside a template instance, and that template is used in
more than one shared library/dll? At least on Windows I'm assuming that
each dll gets it's own instance of the template, and we end up with two
different versions of the static data with unpleasant results. Other than
"don't do that", does anyone have a design or usage pattern that sidesteps
this issue?

This isn't a hypothetical question either, Spirit is using call once like
this inside object_with_id_base<TagT, IdT>::acquire_object_id and perhaps
elsewhere as well.

It's also a fundamental requirement for custom iostream manipulators to be
able to call std::ios_base::xalloc exactly once and store the returned ID
for future reference by all subsequent calls, regardless of which shared
library or dll they may be in. Incidentally both Boost.Fusion and
Boost.Tuples call std::ios_base::xalloc without a call_once guard (so are
not thread safe?), and presumably have the multiple-instantiations in
different modules problem as well.

Looks for a cunning answer yours, John.

Boost list run by bdawes at, gregod at, cpdaniel at, john at