전역 변수를 만들어놓았지만, 전역 변수가 초기화 되기 전에 사용되면서 크래시가 발생하는 경우가 있다.
이것을 Static Initialization Order Fiasco(정적 초기화 순서 실패, 정적 초기화 순서 재앙) 이라고 불린다.
참고 : https://en.cppreference.com/w/cpp/language/siof
Static Initialization Order Fiasco - cppreference.com
The static initialization order fiasco refers to the ambiguity in the order that objects with static storage duration in different translation units are initialized in. If an object in one translation unit relies on an object in another translation unit al
en.cppreference.com
예를 들어 아래와 같이 NamePool이라는 전역 객체가 있을 때 FName 객체의 생성자를 호출했을 때 NamePool 객체가 생성이 되지 않은 상태에서 NamePool에 데이터를 넣으려다가 크래시가 발생할 수 있다.
std::unordered_map<uint64, FString> NamePool;
FName::FName(FStringView InString)
{
FString String = InString.data();
HashCode = Hash(String.data());
NamePool[HashCode] = String; // <- 여기서 Crash
}
FName::FName(const WIDECHAR* InString)
:FName(FStringView(InString))
{
}
FString FName::ToString() const
{
FString Out;
ToString(Out);
return Out;
}
void FName::ToString(FString& Out) const
{
if (HashCode == 0)
{
return;
}
Out = NamePool[HashCode];
}
이를 방지하기 위해선 아래와 같이 코드를 수정하면 된다.
std::unordered_map<uint64, FString>& GetNamePool() // <- 이 함수가 중요
{
static std::unordered_map<uint64, FString> NamePool;
return NamePool;
}
FName::FName(FStringView InString)
{
FString String = InString.data();
HashCode = Hash(String.data());
GetNamePool()[HashCode] = String;
}
FName::FName(const WIDECHAR* InString)
:FName(FStringView(InString))
{
}
FString FName::ToString() const
{
FString Out;
ToString(Out);
return Out;
}
void FName::ToString(FString& Out) const
{
if (HashCode == 0)
{
return;
}
Out = GetNamePool()[HashCode];
}
이 방법을 "Construct on First Use" 아이디엄 이라고 부른다.
참고 : https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Construct_On_First_Use
More C++ Idioms/Construct On First Use - Wikibooks, open books for an open world
From Wikibooks, open books for an open world Ensure that an object is initialized before its first use. Specifically, ensure that non-local static object is initialized before its first use. Lazy construction/evaluation Static objects that have non-trivial
en.wikibooks.org
'Basic Programming > C, C++' 카테고리의 다른 글
C/C++ - Reflection Library (RTTR, ENTT::META) (0) | 2025.04.13 |
---|---|
C/C++ - QueueUserAPC (0) | 2023.04.20 |
C/C++ - Interrupt 감지 (0) | 2023.04.07 |
C/C++ - push_macro() (0) | 2022.10.12 |
C/C++ - vcpkg에서 MT, MD 변경 방법 (0) | 2022.02.17 |