我有 C++ 代码,它声明了由函数调用初始化的静态生命周期变量。被调用函数构造一个vector
实例并调用它的push_back
方法。代码是否因 C++ 静态初始化顺序失败而面临毁灭性风险?如果不是,为什么不呢?
补充信息:
什么是“静态初始化顺序失败”?
在 C++ FAQ 10.14 中有解释
为什么我会认为使用 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);
最佳答案
幸运的是,static
对象甚至在执行其他任何 初始化之前(甚至在相同对象的“真正”初始化之前)就被零初始化了,所以你知道NULL
将在 Register
首次调用之前很久就设置在该指针上。1
现在,就对 vector 进行操作而言,(技术上)您可能会遇到这样的问题:
[C++11: 17.6.5.9/3]:
A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const arguments, includingthis
.
[C++11: 17.6.5.9/4]:
[Note: This means, for example, that implementations can’t use a static object for internal purposes without synchronization because it could cause a data race even in programs that do not explicitly share objects between threads. —end note]
请注意,尽管本说明中要求同步,但在最终确认 static
实现细节的段落中提到了这一点。
话虽如此,该标准似乎应该进一步说明用户代码应避免在静态初始化期间在标准容器上操作,如果其意图是无法保证此类代码的语义;无论哪种方式,我都认为这是标准中的缺陷。应该更清楚了。
关于c++ - 在静态初始化期间创建和使用 vector 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24253799/