C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 变量的静态初始化失败大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我偶然发现了一个问题.

突然间,我正在处理的项目停止了工作.我正在使用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;

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

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

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

// .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()之后观察i的值,并且第一次使用geTinstance()时,我会得到两个不同的地址:

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

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

我不知道这是怎么可能的,因为(init())只调用一次(和之前(geTinstance()`)

解决方法

在不同的转换单元中声明静态范围的对象时,它们的相对构造顺序是未指定的.

例如,如果你试图从作为构造函数的一部分运行的代码中使用MyClass :: Data作为其他一些静态范围的对象,那么在其他一些翻译单元中,没有指定MyClass :: Data是否正在运行在另一个静态范围的对象的构造函数之前或之后构造.如果调用访问MyClass :: Data的代码,并且尚未构造MyClass :: Data,那么这显然是未定义的行为.

在大多数常见的C实现中,构造的顺序取决于链接器将最终可执行文件拼凑在一起的作用;现在,对整个应用程序的各种更改完全有可能导致链接器以不同的顺序将不同的对象模块拼接在一起,并更改静态范围对象的相对构造顺序.

许多实现提供特定于实现的机制来控制静态范围对象的构造/初始化顺序.例如,gcc有一个init_priority属性可用于控制它,参见@L_673_27@

大佬总结

以上是大佬教程为你收集整理的c – 变量的静态初始化失败全部内容,希望文章能够帮你解决c – 变量的静态初始化失败所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。