static unordered_map is erased when putting into different compilation unit in XCode

旧时模样 提交于 2019-12-02 04:33:31

The order of initialization of global objects is defined only within one translation unit. Between different translation the order isn't guaranteed. Thus, you probably see behavior resulting from the std::unordered_map being accessed before it is constructed.

The way to avoid these problems is to not use global objects, of course. If you realky need to use a global object it is best to wrap the object by a function. This way it is guaranteed that the object is constructed the first time it is accessed. With C++ 2011 the construction is even thread-safe:

T& global() {
    static T rc;
    return rc;
}

Thanks, guys! Following Dietmar's advice, I did this:

class C{
//...
private:
  static unordered_map<string, string*>& m();
};

unordered_map<string, string*>& C::m()
{
  static unordered_map<string, string*> m;
  return m;
}

and then I kept referring to m(). It is strange that it did not happen before. I guess I got lucky. But then, this should be a case for a warning message, shouldn't it?


To avoid mistakes like this I will use the following macros to declare and define static variables:

/// Use this macro in classes to declare static variables
#define DECLARE_STATIC(type, name) static type& name();

/// Use this macro in definition files to define static variables
#define DEFINE_STATIC(type, name) type& name(){static type local; return local;}

Usage in this case:

class C{
//...
private:
  DECLARE_STATIC(unordered_map<string, string*>, m);
}
DEFINE_STATIC(unordered_map<string, string*>, m)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!