块范围静态的析构函数可以调用多次
Destructors of block-scope statics can be called several times?
我刚刚阅读了这篇关于当前boost::mutex
实现背后的实际原因的文章,并注意到以下短语:
块范围静力学具有潜在竞争的附加问题条件为"第一次通过",这可能导致析构函数在流行的编译器上多次运行未定义的行为——编译器通常使用对atexit,以确保以相反的方式进行破坏构造顺序,以及可能导致构造函数运行两次也可能导致析构函数注册两次
这是真的吗?我真的应该通过原子操作或类似的操作来检查另一个线程是否已经在这个对象的析构函数中了吗?即使在C++11-C++14中我也应该这样做吗?因为据我所知,自从C++11以来,就不再有"可以从多个线程同时调用具有静态存储持续时间的同一本地对象的构造函数"的问题了——它要求另一个线程等待构造函数完成。我说得对吗?
这篇文章看起来像是在C++11之前写的,它说的还有:
〔…〕C++标准的下一个版本,计划于2009年发布。〔…〕
这是C++11之前的情况,由于线程不是C++11之前内存模型的一部分,所以没有说明在这种情况下发生了什么。
这在C++11中发生了变化,C++11标准草案6.7
声明声明说(强调矿):
所有块范围变量的零初始化(8.5)存储持续时间(3.7.1)或线程存储持续时间(3.7.2)为在进行任何其他初始化之前执行。[…]否则这样的变量在控件第一次通过时被初始化其声明;这样的变量被认为是在完成其初始化。如果初始化通过退出抛出异常,初始化未完成,因此它将下次控件进入声明时重试如果控件同时进入声明,而变量为初始化后,并发执行将等待完成初始化[…]
在C++11之前,我们必须像处理任何其他关键部分一样处理静态局部变量。我们可以在C++作用域后的静态初始化中找到对C++11之前的情况的极好描述,这是故意的!。
- 什么时候调用析构函数
- C++-明确何时以及如何调用析构函数
- C++ 防止在映射中放置()时调用析构函数
- 调用析构函数以释放动态分配的内存
- C++:使用方法调用析构函数的顺序是什么?
- 向量推回调用析构函数时调用析构函数
- 如何在调用析构函数时优雅地停止/销毁带有阻塞调用C++线程?
- C++,我应该调用析构函数吗?
- 如何获取有关在 Clang LibTooling 中调用析构函数的信息?
- 当我从 std::vector 中的新放置调用析构函数时会发生什么?
- 为什么这里不调用析构函数
- 在调用 std::bind 的产品后意外调用析构函数
- 为什么在传递给函数而不是构造函数时调用析构函数?
- 如何在C++中调用析构函数
- 为什么为未删除的对象调用析构函数?
- 调用析构函数时出错
- C++ 在不释放内存的情况下调用析构函数
- 为什么在运算符删除中不调用析构函数?
- C++ 调用析构函数后动态模板队列"double free or corruption (out)"
- 在 postOrderDelete 上调用析构函数时引发的异常