aec*_*ley 8 c++ stdvector static-initialization
我有C++代码,它声明了由函数调用初始化的静态生命周期变量.被调用的函数构造一个vector实例并调用其push_back方法.代码是否会冒险通过C++静态初始化命令惨败?如果没有,为什么不呢?
补充资料:
什么是"静态初始化命令惨败"?
为什么我认为使用vector会引发惨败?
vector构造函数可能会使用动态初始化的另一个静态生命周期变量的值.如果是这样,那么vector在我vector在代码中使用之前,没有什么可以确保变量被初始化.初始化result(参见下面的代码)可能会vector在vector完全初始化依赖项之前调用构造函数,从而导致访问未初始化的内存.
这段代码到底是什么样的?
struct QueryEngine {
QueryEngine(const char *query, string *result_ptr)
: query(query), result_ptr(result_ptr) { }
static void AddQuery(const char *query, string *result_ptr) {
if (pending == NULL)
pending = new vector<QueryEngine>;
pending->push_back(QueryEngine(query, result_ptr));
}
const char *query;
string *result_ptr;
static vector<QueryEngine> *pending;
};
vector<QueryEngine> *QueryEngine::pending = NULL;
void Register(const char *query, string *result_ptr) {
QueryEngine::AddQuery(query, result_ptr);
}
string result = Register("query", &result);
Run Code Online (Sandbox Code Playgroud)vector不依赖于任何阻止其在静态动态初始化中使用的因素。您的代码的唯一问题是缺乏线程安全性 - 没有特别的理由认为您应该关心这一点,除非您有其构造会产生线程的静态变量......
\n\n初始化
\nresult(参见下面的代码)可能最终会在该类完全初始化之前调用向量构造函数,从而导致访问未初始化的内存。
不...初始化result调用AddQuery检查if (pending == NULL)- 根据 3.6.2/2,初始化NULL肯定会在任何动态初始化之前完成:
\n\n执行常量初始化:
\n...
\n\xe2\x80\x94如果具有静态或线程存储持续时间的对象未由构造函数调用初始化,并且该对象是值初始化的或其初始值设定项中出现的每个完整表达式都是常量表达式
\n
因此,即使result作业位于不同的翻译单元中也是安全的。参见 3.6.2/2:
\n\n零初始化和常量初始化一起称为静态初始化;所有其他初始化都是动态初始化。静态初始化应在任何动态初始化发生之前执行。
\n