【问题标题】:static variables do not get initialized静态变量没有被初始化
【发布时间】:2017-08-16 01:59:15
【问题描述】:

我们正在尝试从 RHEL 6.7 迁移到 RHEL 7.3 以及从 gcc 4.4.7 迁移到 gcc 4.8.5。

我们的静态变量(在类定义之外初始化)都没有被初始化。示例,在文件 unitprot_selfsintent.cc 中:

util_Registry<unitprot_SelfsIntent> * unitprot_SelfsIntent::d_selfsIntents = 
    new util_Registry<unitprot_SelfsIntent>();

d_selfsIntents 在 unitprot_selfsintent.h 中被声明为静态的。

util_Registry 是一个模板类。我们第一次尝试在此注册表中放置某些内容时,应用程序核心会转储。 d_selfsIntents 为 0 指针,尚未初始化。

在我们尝试将某些内容放入注册表之前很久,我就认为这已经完成了。

在旧配置下一切正常。在新配置中可能发生了什么变化导致这种情况。我需要调用一个新的编译器选项吗?

更多信息...

另一个类,unit_groundresunitc2.cc,有一个静态变量,定义如下:

static unitprot_Selfintent * f_en_route_to_escort =
    unitprot_SelfsIntent::registerObject("en_route_to_escort");

unitprot_SelfsIntent::registerObject 看起来像这样:

unitprot_SelfsIntent * unitprot_SelfsIntent::registerObject(const char * si)
{
    OTC_String selfsIntent(si);
    return registerObject(selfsIntent);
}

使用 OTC_String 调用 registerObject 如下:

unitprot_SelfsIntent * unitprot_SelfsIntent::registerObject(const OTC_String & si)
{
    unitprot_SelfsIntent * regObj = d_selfsIntents->find(si);

    if (regObj == 0)
    {
        regObj = new unitprot_SelfsIntent(si);
        d_selfsIntents->registerObject(regObj);
    }

    return regObj;
}

在 util_Registry 的 d_selfsIntents 上调用 find(const OTC_String & name) 会导致核心转储,因为 d_selfsIntents 尚未初始化。

所以要回答 Matteo 的问题,是的,我们正在尝试从另一个静态构造 (f_en_route_to_escort) 的初始化中访问静态构造 (d_selfsIntents)。

我发现在初始化另一个之前使用一个问题。我可能有一个问题是为什么现在这是一个问题?他的建议听起来像是早就应该处理的事情。我们的代码有数百个这样的示例,并且已经开发了超过 15 年,直到现在从未出现过问题。

什么设置顺序,编译器还是链接器?这里讨论的两个编译单元是 unitprot(用于 unitprot_SelfsIntent)和 util(用于 util_Registry)。我们确实按特定顺序编译它们,但我认为问题发生在链接时或运行时。

谢谢你,
斯格拉斯哥

【问题讨论】:

  • Google 静态初始化命令惨败。一开始只是运气好,现在运气已经用完了。这就是生活。

标签: linux gcc rhel7


【解决方案1】:

我想念的问题是,您是在其他静态数据成员初始化期间还是在执行已经进入 main 之后尝试访问这些静态数据成员。

如果是第一种情况,请注意,相对于在不同编译单元中定义的那些,变量的静态初始化不能保证以任何特定顺序发生。

可能有一些技巧可以对此进行改进,但处理此问题的常用方法是在充当这些成员的公共 getter 的静态方法中完成初始化。简而言之,这相当于使用单例模式。

您的示例在标题中将如下所示:

class unitprot_SelfsIntent : ...
{
public:
  static util_Registry<unitprot_SelfsIntent>* GetSelfsIntents();
//...
private:
  static util_Registry<unitprot_SelfsIntent>* d_selfsIntents;
//...
};

你的实现类似于:

util_Registry<unitprot_SelfsIntent>* unitprot_SelfsIntent::GetSelfsIntents()
{
  // usually multithreading would be handled here

  d_selfsIntents = new util_Registry<unitprot_SelfsIntent>();

  // some more synchronization

  return d_selfsIntents;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-22
    • 2010-12-22
    • 2022-01-02
    • 2010-09-26
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多