gpt4 book ai didi

c++ - 内置对象/库的静态初始化顺序失败

转载 作者:可可西里 更新时间:2023-11-01 18:39:29 26 4
gpt4 key购买 nike

如果我有一些静态初始化的变量(在 main 开始之前),我是否可以自由使用这些构造函数中的任何内置内容,例如 <iostream><vector>

“静态初始化顺序失败”的发生是因为静态变量的初始化顺序(在不同的翻译单元中)是未定义的。

那么如果像这样的良性东西呢

std::cout << "Hello" << std::endl;

恰好依赖于内部的一些静态变量<iostream>提前初始化? (我不是说它确实如此,但假设它确实如此。)内置库中的这些静态变量在我自己的静态变量之前被初始化怎么说?喜欢里面说 "Person.cpp"或其他。

编辑: Is std::cout guaranteed to be initialized?被建议作为这个问题的拷贝。但是,我认为我的问题范围更广,因为它询问的是任何 标准内置库,而不仅仅是 <iostream>。 .

最佳答案

C++ 标准没有对 main 开始之前或 main 完成之后的程序行为做出强有力的声明。

根据经验,我发现了一些问题,其中 C++ 运行时破坏了某些对象(例如,用于管理 std::mutex 的资源),这在复杂类型的破坏中造成了死锁。

我会为静态的推荐以下模式

C++ 按照执行顺序在函数中创建声明为静态的对象。这留下了一种模式,可确保对象在需要时存在。

   AnObject * AnObject::getInstance() {
static AnObject a;
return &a;
}

应该执行此操作以获取全局变量,并将在调用 getInstance() 时发生。

C++ 11 以上

此代码保证是线程安全的,如果多个执行线程到达 getInstance,只有一个线程会构造对象,其余线程会等待。

C++ 11 之前

创建此模式可替换具有线程安全问题的错误定义顺序。

幸运的是,可以在 main 中创建一个能够进行仲裁的临界区/互斥原语。

在一些操作系统中(例如 InitializeCriticalSection 和 Windows),这些锁可以在 main 之前作为静态变量安全地创建。

   AnObject * AnObject::getInstance() {
EnterCriticalSection( &aObjectcrit );
static AnObject a;
LeaveCriticalSection( &aObjectcrit );
return &a;
}

假设您已经在调用此函数期间或之前初始化了 aObjectcrit。

这种模式的结果是一种洋葱构造形式,其中对象按需要的顺序被需要,当程序退出时,它们按照创建时的相反顺序被销毁。

关于c++ - 内置对象/库的静态初始化顺序失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36563223/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com