views:

73

answers:

5

My experience tells me that given an object:

class Object
{
private:
    static int array[];

public:
    Object(int id);
};


int Object::array[] = { 2937, 892 };


Object::Object(int id)
{
    // do something
}

The initialization of array will happen before the invocation of any method on Object or the invocation of any method on any other object in the program whether the object is declared static or not.

Basically, what I'm asking is does anyone disagree that static simple C types (non-objects) like char, short, int, and long (and structs without constructors composed of those types) are initialized when an executable is loaded into memory, before main() or any other constructor is invoked?

+2  A: 

I guess it's compiler and compiler-option dependant, but your compiler might very well just put the values in the program at compile time if those values are litteral (written as is in the code, as in your example).

I think any decent compiler will do that. Then when your exe is loaded in memory, it already have the values hard-coded.

Klaim
+7  A: 

Yes, all static initialization happens before main() is called. But you cannot be sure in what order the initialization happens. This can cause havoc when one static variable depends on the existence of another. It's called the static initialization fiasco: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14

I often use the solution mentioned in the faq. Use functions with static variables inside to control the order better.

miked
Only the FAQ calls it a fiasco. 1) Also note that the order is well defined within a compilation unit. 2) You should not have that many globals anyway. 3) Globals that are completely unrelated should not be dependent on each other (if they are they will be in the same compilation unit). So hardly a fiasco only as its only a real problem if you are completely incompetent (ie not following any best practices).
Martin York
+4  A: 

This is indeed the case. What is not guaranteed is the order that static members in different translation units are initialised with respect to one another.

Oli Charlesworth
@GMan: Good point; answer updated.
Oli Charlesworth
A: 

The Standard only says that statics are initialized before control enters a scope in which they could be accessed. It doesn't define anything else. I think that file-scope variables are a different thing, but in general, using statics and depending on static behaviour is a bad idea.

DeadMG
+7  A: 

The specific type of initialization that I think you're talking about:

Basically, what I'm asking is does anyone disagree that static simple C types (non-objects) like char, short, int, and long (and structs without constructors composed of those types) are initialized when an executable is loaded into memory, before main() or any other constructor is invoked?

I assume you mean that the initialization with constants - not by calling a function. If that assumption is correct, then yes you can be sure that initialization will happen before any constructors are called:

  • 3.6.2 initialization of non-local objects

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.

However an initalization such as

static int x = getvalue();

falls into the dynamic initialization category, so it gets ordered by appearance (and indeterminately between different translation units).

Another caveat is that this doesn't apply to local statics (which might not be initialized until their block is entered), but that really doesn't matter since they aren't accessible to anything else until the enclosing block has been entered anyway.

Michael Burr
Yup, and the definition of "POD type" gets technical, but pretty much matches the OP's concept describing "simple C types ... and structs without constructors composed of those types". (Plus it's recursive, so you can have structs in structs.)
aschepler