From: Simon Hammett (div0_at_[hidden])
Date: 2008-03-03 04:23:54
On 02/03/2008, John Maddock <john_at_[hidden]> wrote:
> 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.
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
vc 7.1 and above offers __declspec(selectany)
This used by Atl to ensure only one Atl module gets created I believe.
Not used it myself though...
-- The truth is out there. Usually in header files.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk