Written by
Sangwan Kwon
on
on
c++ static member initialization 주의사항
variable의 lifetime을 global하게 가져가기 위해
C++에서 class member 변수로 또는 일반적으로 static 변수를 사용하는데
class member 변수로 사용할 경우 header에서 선언(class declaration)하고
.cpp(member definition or initialization) 에서 초기화를 진행한다.
이 변수들을 참조하기 전에 주의할 점이 초기화 타임이다. 일반적으로 아래와 같이 static initialization이 먼저 난다.
// logger.h
class Logger {
public:
static void setTag(const std::string& str);
private:
static std::string sTag;
static std::string dTag;
};
// logger.cpp
// static initialization
std::string Logger::sTag = "Default";
// dynamic initialization
std::unique_ptr<std::string> Logger::dTag([]() {
auto tag = Logger::getTag();
return tag.empty() ? new std::string("Defualt") : new std::string(tag);
}());
void Logger::setTag(const std::string& str) {
}
Formally, C++ initializes such variables in three phases:
- Zero initialization
- Static initialization
- Dynamic initialization all static objects (objects with static lifetime) are first zero initialized,
then objects with static initialization are initialized,
and then dynamic initialization occurs.
주의사항
- 이 라이브러리 내 sTag가 initialization 되는 시점
- 이 라이브러리를 사용하는 client에서 setTag로 initialization 되는 시점
위 두 경우의 순서를 보장 받을 수 없기에,
dTag처럼 값이 있으면 그 값을 사용 할 수 있도록 해야한다.
(2가 먼저 될경우 ex. attribute((constructor)) // main함수보다 먼저 실행)
이를 하기 위해 dTag는 포인터로 선언되어 있어야 한다. 아니면 segmetation fault
선언만 되어있고 그 값을 setTag로 먼저 참조하므로
결론
- static member를 포인터로 선언
- static member initialization 전 값 확인
ref : http://stackoverflow.com/questions/17783210/when-are-static-and-global-variables-initialized