Initialization and deinitialization order

C

Christopher

I am really getting tired of working through defects that relate to
initialization order problems, so I've taken to documentating
everything I can find on init order, problems and solutions.

I've read over the C++ FAQ section 10 and got a few things, but I
still have quite a few questions.

When do static data members get initialized in relation to the class
itself and global variables?
Note - I read how to wrap them in methods, but am still interested.

When you have a executable process that loads libs or dlls, what is
the order of intialization for global variables in each?
Does the executable have its globals before the libs or dlls? or
vica versa?

When are const members initialized? such as class A{ private: const
int x;}

At what point are static member functions useable?

I read that you can force deinitialization order by controlling the
intialization order. Such that if I have a static instance of class A
that makes use of a static instance of class B in A's destructor, that
I can create a static instance of B in the constructor of A to force
the static instance B to be destroyed last. Is that correct?
 
J

Joshua Maurice

When do static data members get initialized in relation to the class
itself and global variables?
  Note - I read how to wrap them in methods, but am still interested.

I don't know what it means for a "class to be initialized". There is
no such thing in standard C++, nor as commonly implemented. A class is
not an object. Objects are merely regions of memory. Objects of class
type are merely regions of memory with associated functions.

Static member sub-objects are initialized at the same time and in the
same way as namespace scope objects. Namespace scope objects and
static member sub-objects are initialized in the order that they
appear in the object file, and the order of construction between
object files is unspecified.
When you have a executable process that loads libs or dlls, what is
the order of intialization for global variables in each?
  Does the executable have its globals before the libs or dlls? or
vica versa?

Regularly statically linked objects are different than regularly
statically linked libraries, and both are different than are different
than shared-objects (aka DLLs).

The static initialization order between statically linked objects is
unspecified.

A statically linked library is merely a collection of object files,
and most linkers will simply include the referenced object files in
the final executable, so see above.

A shared-object (aka DLL) opened with an explicit call to dlopen will
have its static initialization happen after the call to dlopen. I
don't know offhand for implicitly loaded shared-objects (aka those
which are specified to the linker).
When are const members initialized? such as class A{ private: const
int x;}

Const non-static member sub-objects are initialized during
construction of the containing object, as specified in the
constructor. (Non-const objects may not be initialized during the
construction of the containing object - again see the containing
object's constructor.)
At what point are static member functions useable?

Always. There is no initialization necessary. They are commonly
implemented in the same way as namespace scope functions, aka "stand
alone" functions. Related: pointers to such functions are of the same
type as namespace scope functions.
I read that you can force deinitialization order by controlling the
intialization order. Such that if I have a static instance of class A
that makes use of a static instance of class B in A's destructor, that
I can create a static instance of B in the constructor of A to force
the static instance B to be destroyed last. Is that correct?

Correct. Let's name the objects instead. X uses Y in X's destructor,
so we need Y to outlive X, and thus we need Y to "start living" before
X. Thus we need to guarantee that Y's constructor call finishes before
X's constructor call finishes. One way to accomplish this is to ensure
that Y's constructor is called in X's constructor (or earlier).

Usually, the better solution is to not destroy static objects whose
resources the OS will reclaim, and let them leak.
 
B

Balog Pal

Christopher said:
When do static data members get initialized in relation to the class
itself and global variables?

Same rules apply as to any global or static objects at namespace scope. (see
section 3.6 in the standard)
When you have a executable process that loads libs or dlls, what is
the order of intialization for global variables in each?

Implementation-defined. Can happen before main() is invoked, or may be
postponed. In latter case still must happen before in a translation unit a
function is called or a defined object gets used. Certainly that must be
tweaked for functions that are involved in initialisation itself.

If you're really into it, I suggest to get Matthew Wilson's Imperfect C++
and read the relevant sections, it covers most practical cases and provide
neat solutions too.
 
C

Christopher

Another question on the topic is: What is the order on construction
for multiple inheritace?
I've found a description for single inheritance that goes like this:

1. Memory for derived object is set aside (enough for both the base
and derived portions).
2. The appropriate derived constructor is called.
3. The base object is constructed using the appropriate base
constructor.
4. The derived initialization list initializes variables.
5. The body of the derived constructor executes.
6. Control is returned to the caller.

Is there an order of which object is constucted first if A is derived
from B and C?
What if A is derived from B and C, while B and C are both derived from
D?
 
V

Victor Bazarov

Another question on the topic is: What is the order on construction
for multiple inheritace?

The order of constructing the subobjects of base classes corresponds to
the order of their declaration.
I've found a description for single inheritance that goes like this:

1. Memory for derived object is set aside (enough for both the base
and derived portions).
2. The appropriate derived constructor is called.
3. The base object is constructed using the appropriate base
constructor.
4. The derived initialization list initializes variables.

... or it doesn't. The order of their initialization is defined by the
order of their declaration in the class definition.
5. The body of the derived constructor executes.
6. Control is returned to the caller.

Is there an order of which object is constucted first if A is derived
from B and C?

Yes, if A derives from B and C, first the B subobject is constructed,
then the C one.
What if A is derived from B and C, while B and C are both derived from
D?

Depends on whether D is virtual base or not. If it's a virtual base,
then it's constructed first, then B and then C. If not, each B and C
constructor will construct their own Ds.

V
 
K

Krice

I am really getting tired of working through defects that relate to
initialization order problems

That's an user error. You mess up the init order, you fail.
It's really that simple and everything you need to know about
this subject.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top