其他分享
首页 > 其他分享> > c-在XCode中放入不同的编译单元时,将删除静态unordered_map

c-在XCode中放入不同的编译单元时,将删除静态unordered_map

作者:互联网

我的类C中有一个静态的unordered_map.如果将我的类定义和声明放在包含函数main的文件中的不同文件中,则会遇到行为上的差异.

问题是,我观察到,如果类C与函数main位于同一编译单元中,那么一切都很好,我只看到一次文本“ new string created:c”.但是,如果我将代码分成三个文件(请参见下面的清单),则会看到两次“创建新字符串:c”,这意味着我的静态unordered_map会在进入main之前被擦除.

我的问题是:为什么会这样? (差异仅在使用Apple LLVM编译器4.1进行编译时发生.我已经使用g 4.7 -std = c 11对其进行了测试,并且拆分代码工作得很好.)
预先感谢您的任何想法!

// would go to My_header.h

#include <unordered_map>
#include <string>
#include <iostream>

using namespace std;    

class C{
public:
  C(const string & s);
private:
  static unordered_map<string, string*> m;
  string *name;
};

// would go to My_code.cpp    
// (when separated, add #include "My_header.h")

unordered_map<string, string*> C::m;

C::C(const string & s):
name(NULL)
{
  string*& rs = m[s];
  if(rs)
  {
    name = rs;
  }
  else
  {
    cout<<"new string created: "<<s<<endl;
    rs = name = new string(s);
  }
}

// would go to main.cpp
// (when separated, add #include "My_header.h")

C c("c");

int main(int argc, const char * argv[])
{
  cout << "main" << endl;
  C c1("c");
}

解决方法:

全局对象的初始化顺序仅在一个转换单元内定义.在不同的翻译之间,不能保证顺序.因此,您可能会看到由于在构造std :: unordered_map之前对其进行访问而导致的行为.

当然,避免这些问题的方法是不使用全局对象.如果您确实需要使用全局对象,则最好用函数包装该对象.这样可以确保在第一次访问对象时就构造该对象.在C 2011中,该结构甚至是线程安全的:

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

标签:unordered-map,c,c11,xcode4-5
来源: https://codeday.me/bug/20191013/1908632.html