我正在编译一个包含两个编译单元的共享库:globals.cpp
和stuff.cpp
。 globals.cpp
文件初始化了stuff.cpp
中使用的一些外部变量。我遇到的问题是stuff.cpp
中的代码在globals.cpp
中的代码有机会为extern变量赋值之前正在运行。例如,我看到使用了一堆0
个值。这个问题取决于我编译/运行代码的平台 - 一些工作,一些不工作。
如何解决这个问题?我可以先强制globals.cpp
运行吗?
答案 0 :(得分:6)
你不能(以一致的方式)
但你可以解决它。
global.cpp
// If you have a global variable that has to be initial by a constructor
MyObj globalX;
// Instead do this
MyObj& globalX() { static MyObj x; return x;}
你还有一个全局变量。但是通过将它放在一个函数中,我们知道它何时被使用。通过使用函数的静态成员,它在第一次调用函数时初始化,但在此之后不会。因此,您知道它将在首次使用之前正确构建。
答案 1 :(得分:2)
从comp.lang.c ++ FAQ中,请参阅:
答案 2 :(得分:0)
我假设您看到这种情况,因为您在没有显式函数调用的情况下进行全局变量的内联初始化。例如globals.cpp:
// top of source file
#include "myincludes.h"
CSomeClass someObject(432);
int global_x = 42;
int global_y = InitY();
全局对象和全局变量初始化顺序的构造函数和析构函数顺序大多是非确定性的。 (我猜测,在没有查阅标准参考页面的情况下,源文件中的变量从顶部声明初始化到底部,但是没有定义“哪个源文件首先出现”的顺序。)
最好的解决方案是不要有任何全局对象(构造函数在库中的任何函数之前运行)或者依赖于全局变量初始化顺序。
最好有一个显式初始化库的函数。也许您需要应用程序在启动时调用此函数,或者在检测到未进行初始化后,库的导出函数调用它。然后初始化你的全局变量。
在我的团队中,严格禁止在“main”(或“DllMain”)之前运行的代码。换句话说,没有全局对象。没有函数来初始化全局。