c++ - 在静态初始化期间创建和使用 vector 是否安全?

标签 c++ stdvector static-initialization

我有 C++ 代码,它声明了由函数调用初始化的静态生命周期变量。被调用函数构造一个vector 实例并调用它的push_back 方法。代码是否因 C++ 静态初始化顺序失败而面临毁灭性风险?如果不是,为什么不呢?

补充信息:

  1. 什么是“静态初始化顺序失败”?

    C++ FAQ 10.14 中有解释

  2. 为什么我会认为使用 vector 会引发惨败?

    vector 构造函数可能会使用另一个动态初始化的静态生命周期变量的值。如果是这样,那么在我的代码中使用 vector 之前,没有什么可以确保 vector 的变量被初始化。初始化 result(参见下面的代码)可能会在 vector 的依赖项完全初始化之前调用 vector 构造函数,从而导致访问未初始化的内存.

  3. 这段代码到底是什么样子的?

    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, including this.

[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 实现细节的段落中提到了这一点。

话虽如此,该标准似乎应该进一步说明用户代码应避免在静态初始化期间在标准容器上操作,如果其意图是无法保证此类代码的语义;无论哪种方式,我都认为这是标准中的缺陷。应该更清楚了。

1 And it is a NULL pointer, whatever the bit-wise representation of that may be, rather than a blot to all-zero-bits.

关于c++ - 在静态初始化期间创建和使用 vector 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24253799/

相关文章:

c++ - 具有私有(private)构造函数和自身静态数组的类

c++ - 类层次结构中的静态初始化顺序

c++ - boost::phoenix::insert 的评估结果

c++ - 抑制 G++ 3.4.6 中的链接错误

c++ - 调用 fork() 后 SSL_accept 挂起

c++ - 使用 std vector 作为库中存储的缓冲区和在另一个库中使用此缓冲区的困难

c++ - 如何在运行时计算 C++ 表达式类型?

c++ - 可以使用隐式构造函数初始化具有此 vector 成员的类吗?

未调用 C++ vector 元素构造函数

java - 由于静态初始化而调用的构造函数