强制在某个静态字段之前初始化全局变量



我希望全局变量的初始化(#A)在静态字段(#B)初始化之前被调用。

目前,一些静态字段在全局变量之前初始化。

GridUtil.h

class GridUtil{
   static Vec4* bPtr_;  //will be filled
   static void initGridCalculationCache();
   static class _init   //helper class
    {
        public:
        _init() { 
        static_iniAll(); 
        }
    } _initializer;
}

GridUtil.cpp

#include "GridUtil.h"
GridUtil::_init GridUtil::_initializer;// (Edit: This line is just added, thank Dietmar Kühl.)
Vec4 b[24];                      //#A executed 3rd : No, this should be the first.
Vec4* GridUtil::bPtr_=b;         //#B executed 1st
void GridUtil::initGridCalculationCache() {
    //.... fill GridUtil::bPtr_ using complex computation //#C executed 2nd
}
结果

从调试来看,以上代码的执行顺序为:-

B->C->A

但是我想:-

A->B->C

我注意到,如果将"Vec4"替换为"int",执行顺序将是:-

A->B->C

目标是使用静态函数(initGridCalculationCache)设置数组(bPtr_)中元素的值,该函数将被自动调用(由类_init帮助)。

如果不可能,正确的方法是什么?

按优先顺序排列的四个明显的解决方案是:

  1. 有全局或static成员变量开始!这些往往会产生大量问题,在使用并发的系统中更是如此。
  2. 使用constexpr对象,因为它们在编译时被初始化。显然,对可以做的事情有一些限制,但编译器会验证对象是否按正确的顺序初始化。
  3. 在翻译单元中,具有静态动态时间的对象从上到下初始化。也就是说,如果变量定义可以实现所需的顺序,则使用适当的顺序。然而,没有可移植的方法来跨翻译单元排序变量初始化。
  4. 当来自不同翻译单元的对象之间存在初始化依赖时,可以使用返回引用的函数local static对象来保证正确的顺序:这些将在第一次访问时构造。

顺序相当简单,通过将它们从二进制文件的. data部分复制到RAM来初始化POD。类在运行时由它们的actor初始化。因此,POD总是在任何具有actor的类之前初始化,只要它们位于相同的静态区域。如果你使用DLL/SO,一切都会变得有趣。

初始化顺序未定义。没有任何保证。如果你明确地需要一个特殊的顺序,在init函数中初始化你的静态变量。

相关内容

  • 没有找到相关文章

最新更新