Assuming that non-local static objects, in separate translation units, are initialized in a special order shall not be done.


Order dependencies lead to hard to find bugs.

Vulnerability and risk

The order of initialization for non-local static objects may present problems. For example, a non-local static object may not be used in a constructor if that object will not be initialized before the constructor runs. At present, the order of initialization for non-local static objects, which are defined in different compilation units, is not defined. This can lead to errors that are difficult to locate.

Mitigation and prevention

The problem may be resolved by moving each non-local static object to its own function where it becomes a local static object. If the function returns a reference to the local static object it contains, then clients may access the object via the function without any of the initialization order problems. Note that the function can be inlined to eliminate the function call overhead. Alternately, one might consider allocating objects in a memory pool or on a stack at startup.

Example 1

  // file 1
  static int32 x = 5;
  // file 2
  static int32 y = x + 1; // Bad assumption. The compiler might not have initialized
                          // static variable x.

The solution is to substitute static local objects for static non-local objects since the creation time is precisely defined for static local objects: the first time through the enclosing function.

Example 2

  inline Resource& the_resource()
      static Resource r;
      return r;

Now clients may at any time reference the Resource object, r, as the_resource() without consideration for the order of initialization among r and any other similarly defined local static objects.