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

标签 c++ c++11 static static-initialization

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

我正在从事的项目突然停止工作。我正在使用 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/

相关文章:

c++ - 从函数插入 vector

c++ - Qt5 应用程序不会在 Ubuntu 上绘制任何窗口

c++ - 使用迭代器排序列表不会对最后一个元素 C++ 进行排序

java - PowerMock的mockStatic()覆盖X.class.y()方法

c++ - std::map 的部分反序列化

c++ - 我什么时候应该真正使用 noexcept?

c++ - 线程上下文的静态存储对象优化

c++ - 为什么 lock_guard 可以通过 unique_lock 得到一个已经锁定的互斥体? - 还有问题

java - Java中使用一个TextField输入多个数据

c++ - 静态函数强制单例模式?