gpt4 book ai didi

c++ - 变量的静态初始化失败

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:17:16 26 4
gpt4 key购买 nike

我无意中遇到了一个问题。

我正在从事的项目突然停止工作。我正在使用 Xcode 5.1.1(LLVM 3.4,clang 5.1)。问题是大多数静态变量在启动时不再初始化。

我没有更改任何可能导致此问题的内容,但我很想知道可能导致此问题的原因以及可能的解决方法。

我说的是简单的情况,例如:

// File.h 
class MyClass {
static std::vector<MyObject*> data;
}

// File.cpp
std::vector<MyObject*> MyClass::data;

通过运行程序,我在尝试向 vector 添加元素时遇到长度异常,意识到它的大小只是一个垃圾值。这发生在其他文件中的其他静态字段上,没有明显的原因。代码本身不用作库,而是按原样编译,到目前为止它运行完美。

编辑:构建发布方案并没有显示问题,只是为了增加更多的不可预测性。

编辑:事情比我预期的还要奇怪。我手动初始化的另一个静态变量也不起作用。违规代码如下:

// .h
class MyClass {
static MyClass* i;
public:
static void init();
static MyClass* getInstance();
}

// .cpp
MyClass* MyClass::i;

void MyClass::init() { i = new MyClass(); }
MyClass* getInstance() { return i; }

现在,如果我在调用 init() 之后以及第一次使用 getInstance() 时观察 i 的值我得到两个不同的地址:

(lldb) p MyClass::i
(MyClass *) $0 = 0x09e36a50

(lldb) p MyClass::i
(MyClass *) $1 = 0x00620000

我不明白这是怎么可能的,因为 (init()) 只被调用一次(并且在 (getInstance()`) 之前)

最佳答案

当您在不同的翻译单元中声明静态范围的对象时,它们的相对构造顺序是未指定的。

例如,如果您尝试使用代码中的 MyClass::Data 作为某些其他静态作用域对象的构造函数的一部分运行,则在某些其他翻译单元中,未指定是否 MyClass::数据将在其他静态范围对象的构造函数之前或之后构造。如果访问 MyClass::Data 的代码被调用,而 MyClass::Data 尚未构造,那显然是未定义的行为。

在大多数常见的 C++ 实现中,构造顺序取决于链接器将最终可执行文件拼凑在一起的方式;并且现在对您的整个应用程序进行的各种更改很可能导致链接器以不同的顺序将不同的对象模块拼接在一起,并更改静态作用域对象的相对构造顺序。

许多实现提供特定于实现的机制来控制静态范围对象的构造/初始化顺序。例如,gcc 有一个 init_priority 属性可以用来控制它,参见 https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

关于c++ - 变量的静态初始化失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25999543/

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