C++ 线程\本地静态类在程序退出时在无效地址处被销毁
我有一个关于销毁本地静态对象的问题C++ 线程\本地静态类在程序退出时在无效地址处被销毁,c++,c++14,thread-local,static-initialization,destruction,C++,C++14,Thread Local,Static Initialization,Destruction,我有一个关于销毁本地静态对象的问题 #include <iostream> #include <thread> struct UsesLoc { UsesLoc() { loc.counter++; } struct Loc { Loc() { std::cout << "I am at " << this << " and counter is "
#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;
}
相反,当我使用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
显然,位于不同内存位置的未初始化对象将被销毁
我监督过任何不确定的事情吗?如何确保正确的对象被销毁?在得到一个消息,这可能是一个编译器错误后,我做了一些研究,这似乎确实是一个以前已经报告过的问题:
也就是说,代码是正确的,指向被破坏对象的指针指向以前在使用标准兼容编译器时构造的同一个对象。我没有答案,但您是否考虑过使用Meyers Singleton而不是class scope静态对象?我不知道后者的线程安全/初始化/销毁保证是什么…您确定它需要是
thread\u local static
,而不仅仅是thread\u local
?这可能是两个关键字的组合造成的。@MaxLanghof如果我理解正确,这意味着将类作用域静态移动到函数作用域静态。我试过了,但没什么变化。我也试着把它移到全局范围,但又是一样的。似乎由于某种原因,对象仅在地址未知的点被销毁。@ALX23z是的,不允许使用thread\u local
非静态成员IIRC。在全局范围内-我也尝试过-thread\u local
和thread\u local static
应该是相同的。我认为这是MinGW中的一个bug。哪个版本?我用一个版本的编译器@godbolt尝试了您的代码,该编译器可以生成运行时输出,但没有一个复制了这个版本。
I am at 0x507874 and counter is 0
loc is at 0x507874 and counter is 1
I was at 0x7efdd000 and counter is 2686552