Reputation: 9359
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];
Upvotes: 3
Views: 802
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
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
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