Re: Threadsafe singletons
Gene Bushuyev wrote:
"David Barrett-Lennard" <davidbl@iinet.net.au> wrote in message
news:1154486385.368936.171210@i3g2000cwc.googlegroups.com...
Gene Bushuyev wrote:
"David Barrett-Lennard" <davidbl@iinet.net.au> wrote in message
news:1154313829.569314.297530@p79g2000cwp.googlegroups.com...
[...]
The GetInstance() function employs the lazy creation approach.
However, the intention is not to avoid consuming resources. In fact
the static InitMySingleton instance is used to force the singleton to
be eagerly initialized before main() begins.
You don't have any guarantee that either one of your objects is
itinitialized
before main (3.6.2/3). The standard only requires that they are
initialized
before the first use, neither static MySingleton nor s_init are used
before
main() in your example.
I think that's a shame. I like to be able to have code knowingly run
before main() begins. For example, to allow factories to self-register
with a singleton factory registry.
Do you know of any compilers that don't execute the s_init
constructor before main()?
No, that's not a shame, that's a compiler optimization :-) An aggressive
optimizing compiler may decide to throw s_init away completely to make
your
program run faster, because it is never used.
The standard says that introducing a side effect in constructor forces
compiler
to initialize the objects. So your unused s_init would be initialized if
its
constructor had a side effect (3.7.1/2). Definition of the side effect is
found
in (1.9/7): "Accessing an object designated by a volatile lvalue (3.10),
modifying an object, calling a library I/O function, or calling a function
that
does any of those operations are all side effects, which are changes in
the
state of the execution environment..."
But don't forget that those side effects must be observable, or compiler
can
disregard them following "as-if" rule.
That suggests it is fairly easy to change the code in my OP to ensure
s_init is initialised. Eg
static volatile int s_dummy;
static struct InitMySingleton
{
InitMySingleton() { s_dummy = 0; MySingleton::GetInstance(); }
} s_init;
To self document this, perhaps I could define a function called
DontOptimiseAway() that has observable side-effects, and simply call it
from the constructor for s_init. Can you think of something more
elegant?
I suppose the technique used to automatically self-register things with
a singleton registry will satisfy the requirements of observable
side-effects (assuming the singleton is actually accessed via main).
Eg
static struct RegisterMyFactory
{
RegisterMyFactory() { FactoryRegistry::GetInstance().Register(new
MyFactory); }
} s_reg;
Cheers,
David Barrett-Lennard
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]