加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 变量的静态初始化失败

发布时间:2020-12-16 07:09:49 所属栏目:百科 来源:网络整理
导读:我偶然发现了一个问题. 突然间,我正在处理的项目停止了工作.我正在使用Xcode 5.1.1(LLVM 3.4,clang 5.1).问题是大多数静态变量在启动时不再被初始化. 我没有改变任何可能导致这个问题的东西,但我很想知道是什么导致了这个问题并且可能解决了这个问题. 我说的
我偶然发现了一个问题.

突然间,我正在处理的项目停止了工作.我正在使用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属性可用于控制它,参见https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读