Martin
Martin

Reputation: 9359

Static data member initialization order

Consider the code below in a single translation unit:

class C {
private:

    struct Init {

        Init() {
            /* compute data once here */
        }
    };
    static const Init& i;
    static int data[];
public:
    /* interface for reading data */
};

const C::Init& C::i = Init();
int C::data[200];
  1. Is C::i always initialized after C::data no matter the order of the definition of both?
  2. Is this solution the most elegant one for computing static data once?

Upvotes: 3

Views: 802

Answers (3)

BЈовић
BЈовић

Reputation: 64203

Is C::i always initialized after C::data no matter the order of the definition of both?

The order is guaranteed if they are defined in the same compilation unit, otherwise not.

Is this solution the most elegant one for computing static data once?

No. If you really have to have it static, then a better way (and to prevent a possible static initialization order fiasco) is to do it like this :

struct someDataStr
{
  int data[200];
};
someDataStr& AccessData()
{
  static someDataStr *ptr = NULL;
  if ( NULL == ptr )
  {
    ptr = new someDataStr;
    // initialize value
  }
  return *ptr;
}

If it doesn't have to be static, then use dependency injection, and pass the object containing data to all classes using it.

Upvotes: 0

Abyx
Abyx

Reputation: 12918

C::data isn't initialized there, so order doesn't matter.

The shorter solution is to use static function and dummy variable:

class C {
private:

    static void Init() {
        /* compute data once here */
    }

    static bool data_init_helper;
    static int data[];
public:
    /* interface for reading data */
};

bool C::data_init_helper = (C::Init(), false);
int C::data[200];

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 476930

int C::data[200] is zero-initialized, which means that it is statically initialized. Static initialization comes before dynamic initialization. Since C::Init::Init() is not a constant expression, C::i is dynamically initialized, necessarily after C::data.

See 3.6.2 for details.

A bootleg quote:

Variables with static storage duration [...] shall be zero-initialized before any other initialization takes place. [...] Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.

Upvotes: 6

Related Questions