Static object not constructed by loader: ctor not called?

G

Guest

Im getting a runtime error because Ive got a static object that is not
properly initialized.

---------- header file xxx.hpp ---------------
class SomeClass {
SomeClass() { .. constructor here ..;}
} // end SomeClass
static SomeClass staticObject; // declaration in header

-------------- in .cpp file: ----
SomeClass staticObject; // definition in .cpp file: constructor called by
loader

When the code is executed at run time, and the static object staticObject
is accessed, I get a failure becuase it's constructor has not been executed
yet (so its data members are not initialized).

Another programmer on my team says that statics (and globals) are okay for
integers, floats, simple arrays (of ints, floats), char[] strings, and for
classes (or structs) that DO NOT have a constructor.

But, he says, one should never use a static/global for an object of a class
that has a constructor, because the loader is very unpredictable, and you
cannot be sure the loader will call the static's constructor before some
software tries to use/access the static.

Can anyone confirm this? Does anyone else have problems using
statics/globals of classes that have constructors.

PS: I should mention that this software is in a DLL (not an application)
that is attached to processes at run time, not link time.
 
C

Carl Daniel [VC++ MVP]

noleander said:
Im getting a runtime error because Ive got a static object that is not
properly initialized.

---------- header file xxx.hpp ---------------
class SomeClass {
SomeClass() { .. constructor here ..;}
} // end SomeClass
static SomeClass staticObject; // declaration in header

That's probably not what you wanted. Change this to

extern SomeClass staticObject;


As is, you're creating an instance of the object in every translation unit
that includes the header.
-------------- in .cpp file: ----
SomeClass staticObject; // definition in .cpp file: constructor
called by loader

When the code is executed at run time, and the static object
staticObject is accessed, I get a failure becuase it's constructor
has not been executed yet (so its data members are not initialized).

Another programmer on my team says that statics (and globals) are
okay for integers, floats, simple arrays (of ints, floats), char[]
strings, and for classes (or structs) that DO NOT have a constructor.

Globals/statics that have constructors are perfectly fine, but you have to
be careful when accessing one static object from within the constructor of
another static object as the order of initialization guarantees provided by
the C++ language specification are well... weak.
But, he says, one should never use a static/global for an object of a
class that has a constructor, because the loader is very
unpredictable, and you cannot be sure the loader will call the
static's constructor before some software tries to use/access the
static.

Can anyone confirm this? Does anyone else have problems using
statics/globals of classes that have constructors.

PS: I should mention that this software is in a DLL (not an
application) that is attached to processes at run time, not link time.

-cd
 
G

Guest

Thanks for the tip. The actual code I have (my snippet above simplified
things) is:

---------- header file xxx.hpp ---------------
class SomeClass {
SomeClass() { .. constructor here ..;}
} // end SomeClass

class OtherClass {
static SomeClass staticObject; // static data member
....
}


---------- xxx.cpp file -----------
static OtherClass::staticObject = {...};
 
C

Carl Daniel [VC++ MVP]

noleander said:
Thanks for the tip. The actual code I have (my snippet above
simplified things) is:

---------- header file xxx.hpp ---------------
class SomeClass {
SomeClass() { .. constructor here ..;}
} // end SomeClass

class OtherClass {
static SomeClass staticObject; // static data member
....
}


---------- xxx.cpp file -----------
static OtherClass::staticObject = {...};

Oh, OK. That's completely different and should be fine. Constructors for
such objects definitely will run, but the order of constructor execution
between globals decalred in different translation units is undefined. If
you're entering this object from another global object constructor in a
different translation unit, you may well touch this object before it's
constructor is run.

-cd
 

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

Top