Skip to content

Commit fbb86ef

Browse files
committed
Fix initialization order problem
C++ standart doesn't guarantee the order of initialization for static members in different modules. So, some modules may try to use non-initialized data in the non-initialized module and get an error. Let's fix this problem using nifty-counter technique.
1 parent 83a67af commit fbb86ef

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

src/utils/xrSE_Factory/ai_space.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,35 @@
1111
#include "xrScriptEngine/script_engine.hpp"
1212
#include "xrServerEntities/object_factory.h"
1313

14-
static CAI_Space g_ai_space;
14+
// Nifty counter required to solve initilization order problem
15+
// Please, do NOT initialize this static members directly, it breaks the initialization logic
16+
// And yes, according to the standard ($3.6.2/1): "Objects with static storage duration (3.7.1) shall be
17+
// zero-initialized (8.5) before any other initialization takes place" So, it must be automatically
18+
// initialized with zeros before executing the constructor
19+
static CAI_Space* s_ai_space;
20+
static u32 s_nifty_counter;
21+
22+
SAI_Space_Initializer::SAI_Space_Initializer()
23+
{
24+
if (s_nifty_counter++ == 0)
25+
{
26+
s_ai_space = new CAI_Space();
27+
}
28+
}
29+
30+
SAI_Space_Initializer::~SAI_Space_Initializer()
31+
{
32+
if (--s_nifty_counter == 0)
33+
{
34+
xr_delete(s_ai_space);
35+
}
36+
}
1537

1638
CAI_Space& CAI_Space::GetInstance()
1739
{
18-
auto& instance = g_ai_space;
40+
VERIFY(s_ai_space);
41+
42+
auto& instance = *s_ai_space;
1943
if (!instance.m_inited)
2044
{
2145
instance.init();

src/utils/xrSE_Factory/ai_space.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ class CAI_Space
4444
bool Unsubscribe(CEventNotifierCallback::CID cid, EEventID event_id) { return true; }
4545
};
4646

47+
// Static initializer for every translation unit
48+
// Need to avoid static initilization order problem
49+
static struct SAI_Space_Initializer
50+
{
51+
SAI_Space_Initializer();
52+
~SAI_Space_Initializer();
53+
} s_AISpaceInitializer;
54+
4755
IC CAI_Space& ai();
4856

4957
#include "ai_space_inline.h"

src/xrGame/ai_space.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,35 @@
2222
#include "moving_objects.h"
2323
#include "doors_manager.h"
2424

25-
static CAI_Space g_ai_space;
25+
// Nifty counter required to solve initilization order problem
26+
// Please, do NOT initialize this static members directly, it breaks the initialization logic
27+
// And yes, according to the standard ($3.6.2/1): "Objects with static storage duration (3.7.1) shall be
28+
// zero-initialized (8.5) before any other initialization takes place" So, it must be automatically
29+
// initialized with zeros before executing the constructor
30+
static CAI_Space* s_ai_space;
31+
static u32 s_nifty_counter;
32+
33+
SAI_Space_Initializer::SAI_Space_Initializer()
34+
{
35+
if (s_nifty_counter++ == 0)
36+
{
37+
s_ai_space = new CAI_Space();
38+
}
39+
}
40+
41+
SAI_Space_Initializer::~SAI_Space_Initializer()
42+
{
43+
if (--s_nifty_counter == 0)
44+
{
45+
xr_delete(s_ai_space);
46+
}
47+
}
2648

2749
CAI_Space& CAI_Space::GetInstance()
2850
{
29-
auto& instance = g_ai_space;
51+
VERIFY(s_ai_space);
52+
53+
auto& instance = *s_ai_space;
3054
if (!instance.m_inited)
3155
{
3256
instance.init();

src/xrGame/ai_space.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ class CAI_Space : public AISpaceBase
9191
IC doors::manager& doors() const;
9292
};
9393

94+
// Static initializer for every translation unit
95+
// Need to avoid static initilization order problem
96+
static struct SAI_Space_Initializer
97+
{
98+
SAI_Space_Initializer();
99+
~SAI_Space_Initializer();
100+
} s_AISpaceInitializer;
101+
94102
IC CAI_Space& ai();
95103

96104
#include "ai_space_inline.h"

0 commit comments

Comments
 (0)