As a general rule of thumb, accessing global data from within class constructors is a dangerous operation and ought to be avoided. The C++ specification does not describe the order in which global variables are initialized, so there are high chances that your constructor accesses uninitialized data, producing unexpected resultsn (e.g., crashes in some circumstances).

It is important to remark this. This behavior is undefined, so it can change across compilers and/or architectures. If your code relies on it, it's broken: something that apparently works on one machine may not work on another one.

Let's see an example. First of all, consider an Integer class that wraps an integer (like Java's one) and a Foo class with a not-yet-specified constructor:

class Integer {
int m_value;

Integer(int v) { m_value = v; }
int get_value(void) { return m_value; }

class Foo {

Up to this point, everything is correct. Now, given that both classes are usable, we declare two global variables, one of each type:

static Integer Global_Integer(5);
static Foo Global_Foo;

As these are objects, the C++ runtime will call their constructors when initializing them, but we can't predict the order in which this will happen.

Now we define Foo's constructor body, which accesses and prints Global_Integer's value:

std::cout << Global_Integer.get_value() << std::endl;

With this done, if you add an empty main function and run the program, you should see an integer; it will be probably be 5 (at least with GNU G++ 4.0.1 on a Linux/powerpc box), but it may not. Whichever value you get, try reversing the variable declaration lines, defining Global_Foo first and see if the results change (I get 0 in this box).

Clear? OK, this example is extremely simple, but imagine if this same structure was split among multiple files and classes in a large project... You couldn't easily predict what happens under the hood.

Subscribe via RSS · Go to posts index

   Delivered by FeedBurner

Comments from the original Blogger-hosted post: