// File: InitFirst.h
#pragma once
template <int val>
struct InitFirst
{
static float s_dividedByThree;
};
template <int val>
float InitFirst<val>::s_dividedByThree = val / 3.0;
// File: Test.h
#include <conio.h>
#include <tchar.h>
#include "InitFirst.h"
float g_shouldBeOneThird = InitFirst<1>::s_dividedByThree;
int _tmain(int argc, _TCHAR* argv[])
{
_cprintf("%f\n", g_shouldBeOneThird);
getch();
return 0;
}
Is g_shouldBeOneThird guaranteed to be initialized to around 0.333? In other words, is the statically initialized InitFirst<1>::s_dividedByThree guaranteed to be initialized by the time it's used for statically initializing g_shouldBeOneThird?
From the standard (3.6.2):
In your case here, since you're initializing
float InitFirst<val>::s_dividedByThree
with a constant expression, this will happen before any dynamic initialization (f.xfloat g_shouldBeOneThird
). Though I have a feeling this simplified example might be a simplification of a case where you have dynamic initialization, then the relevant part is: "Objects defined within a single translation unit and with ordered initialization shall be initialized in the order of their definitions in the translation unit.".There is a trick to make sure that global variables (sort of) are initialised by the time you use them. The trick is to keep them as a static local variable in a global function. Since local static variables are initialised the first time they're accessed, initialisation order is not an issue anymore:
You can then access those variables almost as before:
Beware though, initialization of local static variables are not safe under multiple threads (it's not in the standard that they should be safe). If that is a concern for you, you might want to protect the initializations with some locks. The compilers are of course allowed to generate safe code, which is what gcc does by default (probably others too).