Jakob Bieling said:
Hi,
I am aware of the fact, that the order of construction of global
objects is unspecified.
It is unspecified if they are in different translation units. If they are in
the same translation unit, then construction is in the same order as
definition. Section 3.6.2/1 of the standard:
"Objects with static storage duration (3.7.1) shall be zero-initialized
(8.5) before any other initialization takes place. Zero-initialization and
initialization with a constant expression are collectively called static
initialization; all other initialization is dynamic initialization. Objects
of POD types (3.9) with static storage duration initialized with constant
expressions (5.19) shall be initialized before any dynamic initialization
takes place. Objects with static storage duration defined in namespace scope
in the same translation unit and dynamically initialized shall be
initialized in the order in which their definition appears in the
translation unit."
But I am in a situation, where I need to
guarantee, that one object is created before others (not all others,
just all objects of a specified type). I came up with the following
solution, but I am not sure, if it does solve my problem:
class first
{
};
class A
{
static first first_obj;
};
This only declares first_obj, where do you define it?
int main ()
{
A mya;
}
class A (further implementation omitted) will rely on some
initialization done by class first. Is it guaranteed that this
initialization will be all done, before I use A?
Section 3.6.2/3 of the standard:
"It is implementation-defined whether or not the dynamic initialization
(8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the
first statement of main. If the initialization is deferred to some point in
time after the first statement of main, it shall occur before the first use
of any function or object defined in the same translation unit as the object
to be initialized.31) [Example:
// – File 1 –
#include "a.h"
#include "b.h"
B b;
A::A(){
b.Use();
}
// – File 2 –
#include "a.h"
A a;
// – File 3 –
#include "a.h"
#include "b.h"
extern A a;
extern B b;
int main() {
a.Use();
b.Use();
}
It is implementation-defined whether either a or b is initialized before
main is entered or whether the initializations are delayed until a is first
used in main. In particular, if a is initialized before main is entered, it
is not guaranteed that b will be initialized before it is used by the
initialization of a, that is, before A::A is called. If, however, a is
initialized at some point after the first statement of main, b will be
initialized prior to its use in A::A. ]"
Section 9.4.2/7:
"Static data members are initialized and destroyed exactly like non-local
objects (3.6.2, 3.6.3)."
From all this, we may conclude: the initialization of
static first first_obj;
"shall occur before the first use [in main()] of any function or object
defined in the same translation unit as the object to be initialized [i.e.,
first_obj]." So if first_obj and A are defined in the same translation unit,
first_obj must be initialised before the first use of A in main(). At least
that is how it appears to me.