Re: 'static initialization' vs. 'dynamic initialization'
JohnQ wrote:
"James Kanze" <james.kanze@gmail.com> wrote in message
news:1171536438.699419.123660@j27g2000cwj.googlegroups.com...
JohnQ wrote:
What are the definitions of 'static initialization' and 'dynamic
initialization'?
Formally, zero-initialization and initialization of a POD with a
constant expression (or constant expressions) is called static
initialization, everything else is dynamic.
Now _that_ is a definition I can assimilate. I was getting
confused on how a class object instance could be considered
part of static initialization when constructors have to run to
initialize the object.
If the constructors are trivial, there's no problem. (User
defined constructors are not trivial, by definition.)
All static
initialization occurs before any dynamic initialization (and the
fact that the initializers are constant expressions means that
there can be no ordering dependancies in static initialization).
Do you mean that ordering dependency has to be avoided or that it is
impossible?
Anything which would create a dependancy will in fact prevent
the expression from being constant. Constant expressions are
evaluated by the compiler, and so cannot depend on the execution
of other code. (If you use a const variable of integral type,
whose initializer is an integral constant expression, in the
initialization expression, the initialization expression could
be said to depend on that variable. Of course, in order to do
this, the variable must have been defined and initialized
previously in the translation unit, which means that the order
of initialization would be guaranteed. But I think it is even
more accurate to say that what is used is not the variable, but
the value it is initialized with, so again, there is no
dependancy.)
Note that a compiler is allowed, under certain circumstances, to
replace dynamic initialization with static. If, for example,
the constructors for std::complex<double> are inline (probably
the case), and you write something like:
std::complex< double > z( 1.2, 3.4 ) ;
the compiler is allowed to generate static initialization, as if
complex were a PODS, with no constructors and you had written:
std::complex< double > z = { 1.2, 3.4 } ;
Most of the time, a program won't be able to tell, but there are
exceptions.
[...]
The static in static initialization has nothing
to do with the keyword. What is being discussed is the
initialization of non-local objects with static storage
duration, i.e. objects defined at namespace scope (with or
without the static keyword).
"globals" pretty much, yes?
Not really. At least, not only:
int x = f() ; // global.
static int y = f() ; // global?
namespace {
int z = f() ; // global?
}
The standard doesn't define or use the term globals; it speaks
in terms of object lifetime and linkage. In the above, I would
normally only speak of the first as global, although one might
argue about the third. All have static lifetime, however. (In
the terms of the standard, the first has external linkage and the
second internal linkage; the third has external linkage, but
cannot be named in another translation unit.)
There is also a question about local variables with static
storage duration, e.g.
void
f()
{
static int i = 42 ;
}
According to the standard, these are initialized when the
definition is first encountered during execution, regardless of
whether the initialization is a constant expression or not. In
practice, however, if the initialization would qualify for
static initialization at namespace scope, there's no way a
program can tell if it takes place earlier, and all of the
implementations I know also initialize the variable from the
loaded process image, exactly as they do for variables at
namespace scope. (This is only true for static initialization,
however; any dynamic initialization will not be done until the
definition is reached.)
Such initialization can be
considered to be broken down into three phases:
zero-initialization, constant-initialization and dynamic
initialization. Conceptually, they occur in that order,
although because there is no way in constant-initialization to
determine whether zero-initialization has taken place, most
implementations merge these two steps, and in many contexts, the
standard as well treats them as one, under the name
static-initialization.
OK, good explanation. I get it. I was wondering overall if
there was such an animal as static initialization of class
object instances at "global" (namespace) scope.
Sure:
struct Toto
{
int a ;
int b ;
} ;
Toto x = { -1, 42 } ;
Static initialization of an object with class type at namespace
scope. The critical part related to the type is that the object
must be a POD; POD structs (which have class type) can be
initialized statically, just like any other POD.
Note that anything which prevents POD-ness prevents static
initialization. Any user defined constructor, obviously, but
also any private or protected non-static data members, any
virtual functions, any base classes, a user defined assignment
operator or a user defined destructor.
I was/am investigating the
order-of-initialization-of-global-class-objects problem and was wondering
what the solutions were that didn't cause a bunch of paging at program
startup and termination. Common Singleton techniques appear to cause the
paging problem (not that I've noticed it, just that I've read about it in
D&E).
How does the usual singleton idiom cause paging? I think you're
thinking of the tricky counter idiom, which is relatively little
used today.
Order of initialization can be a serious problem, however, and
one of the main reasons I sometimes use C style arrays instead
of std::vector is precisely to obtain static initialization, and
avoid order of initialization problems. (Similarly, I'll use a
presorted C style array and std::lower_bound rather than
std::map or std::set for constant objects with static lifetime,
in order to avoid order of initialization problems.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientie objet/
Beratung in objektorientierter Datenverarbeitung
9 place Simard, 78210 St.-Cyr-l'Icole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]