我已经习惯了全局/静态类成员的主要的第一行之前发生()的所有初始化的思维。但最近我读的地方,该标准允许初始化以后发生在“协助模块动态加载。”我可以看到这是真的时动态链接:我不希望在库初始化的全局之前,我dlopen'ed库进行初始化。然而,静态链接在一起翻译单元(我的应用程序的直接.o文件)的组内我会觉得这种行为非常不直观。这是否只发生在懒洋洋地动态链接或者它可以发生在任何时候? (或者是我刚刚读错;?)

有帮助吗?

解决方案

该标准中下列3.6.2 / 3:

  

据实现定义是否的对象的动态初始化(8.5,9.4,12.1,12.6.1)   命名空间范围主要在第一条语句之前完成。如果初始化延迟到某个点   在主要的第一条语句之后的时间,应当在第一次使用所定义的任何功能或对象的之前发生   在同一个翻译单元,以初始化该对象。

。可是,当然,你可以从未正式告诉在初始化发生,因为你访问变量之前产生的初始化!作为如下:

// t1.cc
#include <iostream>
int i1 = 0;

int main () {
  std::cout << i1 << std::endl

// t2.cc
extern int i1;
int i2 = ++i1;

我可以符合使g ++ 4.2.4至少出现之前主要执行“I2”的初始化。

其他提示

这一个希望与该规则要解决的问题是动态加载的所述一个。这种补贴不仅限于动态加载和正式可能发生的其他案件。我不知道该用它做别的事情不是动态加载的实现。

让我们回顾一个伪代码:

在DLL:

static int ItsDllVar = 1;
int EXPORTED_FUNCTION() { return ItsDllVar; }

在应用程序:

static int AppVar1 = 2;
static int AppVar2 = EXPORTED_FUNCTION() + AppVar1;

因此,根据静态初始化AppVar2得到1 + 2 = 3

适用于局部静态变量(不管DLL)延迟初始化

int f()
{
    static int local_i = 5;//it get's 5 only after visiting f()
    return local_i;
}

我觉得这是我的情况与G ++ 4.7和CMake的(不知道这是关于CMake的相关细节)发生了什么事。我有一个注册在工厂函数的记号。它依赖于构造从全局初始化的变量调用。

在此代码是在静态链接库的初始化没有发生!它现在工作正常,当我把它移动到直接连接的目标文件(即,它们没有被组合到库第一)。

所以,我怀疑你是正确的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top