thread_local静态类在程序退出时在无效地址处销毁



我对破坏thread_local静态对象有问题。

#include <iostream>
#include <thread>
struct UsesLoc {
UsesLoc() {
loc.counter++;
}
struct Loc {
Loc() {
std::cout << "I am at   " << this << " and counter is " << counter << std::endl;
}
~Loc() {
std::cout << "I was at  " << this << " and counter is " << counter << std::endl;
}
int counter = 0;
};
static thread_local Loc loc;
};
thread_local UsesLoc::Loc UsesLoc::loc;
int main()
{
{
UsesLoc usesloc;
std::cout << "loc is at " << &UsesLoc::loc << " and counter is " << UsesLoc::loc.counter << std::endl;
}
return 0;
}

正如预期的那样,在 https://coliru.stacked-crooked.com/a/e8bcfdaffa6a6da7 上编译和运行会显示 thread_local 对象始终位于同一位置,计数器值为 (0,1,1(:

I am at   0x7f9dc817673c and counter is 0
loc is at 0x7f9dc817673c and counter is 1
I was at  0x7f9dc817673c and counter is 1

相反,当我使用 MinGW 本地编译并运行时,例如,我得到

I am at   0x507874 and counter is 0
loc is at 0x507874 and counter is 1
I was at  0x7efdd000 and counter is 2686552

显然,位于不同内存位置的未初始化对象将被销毁。

我监督过任何不确定的事情吗?如何确保销毁正确的对象?

在从 Ted Lyngmo 那里得到提示这可能是一个编译器错误后,我做了一些研究,这似乎确实是一个之前已经报告过的问题:

  • https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562
  • https://sourceforge.net/p/mingw-w64/bugs/527/
  • https://sourceforge.net/p/mingw-w64/bugs/727/

话虽如此,代码是正确的,并且指向正在销毁的对象的指针指向之前使用符合标准的编译器时构造的同一对象。