Здравствуйте, Кодт, Вы писали:
К>Implementation-defined.
К>Более того, и статические, и потоковые переменные (нелокальные) должны быть инициализированы до первого использования.
К>А будет это до входа в main или нет, — можно делать и так, и этак, и даже вперемешку!
Получается, это может не работать
static GlobalData g_GlobalData;
static thread_local ThreadData g_ThreadData; // ThreadData использует g_GlobalData
т.к.
1. g_ThreadData может быть сконструирован перед g_GlobalData (g_GlobalData отложенная, а g_ThreadData нет. Или треды в статических объектах)
2. g_ThreadData может жить дольше g_GlobalData (Треды в статических объектах)
Чтобы работало надо
std::shared_ptr<GlobalData> GetGlobalData()
{
static auto instance = std::make_shared<GlobalData>();
return instance;
}
static thread_local ThreadData g_ThreadData; // ThreadData в своём конструкторе сохраняет у себя результат GetStaticData()
А чтобы работать в Windows, ещё нужно, чтобы ThreadData по умолчанию был "зомби", и получал свою GlobalData только когда фактически используется.
Потому что из-за стороннего софта к нам могут заходить левые треды в любомй момент, особенно в начале работы, до инициализации рантайма, см тред ниже
[MSVC] Грабли: thread_local могут конструироваться до обычных глобальных