c – 可以多次调用块范围静态的析构函数?

我刚读了一篇关于当前boost :: mutex实现背后的实际原因的
this文章,并注意到以下短语:

Block-scope statics have the additional problem of a potential race
condition on “the first time through”, which can lead to the
destructor being run multiple times on popular compilers, which is
undefined behaviour — compilers often use the equivalent of a call to
atexit in order to ensure that destruction is done in the reverse
order of construction, and the initialization race that may cause the
constructor to be run twice may also cause the destructor to be
registered twice

这是真的吗?我是否应该通过原子操作或类似的方式检查此对象的析构函数中是否已存在另一个线程?即使在C 11 – C 14中我也应该这样做吗?因为据我所知,自从C 11以来,不再有“具有静态存储持续时间的同一本地对象的构造函数可以从几个线程同时调用”问题 – 它要求另一个线程应该等待构造函数的完成.我对吗?

最佳答案 看起来这篇文章是在C 11之前编写的,其中包括:

[…] next version of the C++ Standard, scheduled to be released in 2009.[…]

这是C11之前的情况,由于线程不是C 11之前的内存模型的一部分,所以未指明在这种情况下发生了什么.

这在C 11和draft C++11 standard第6.7节声明中声明改变(强调我的):

The zero-initialization (8.5) of all block-scope variables with static
storage duration
(3.7.1) or thread storage duration (3.7.2) is
performed before any other initialization takes place. […] Otherwise
such a variable is initialized the first time control passes through
its declaration; such a variable is considered initialized upon the
completion of its initialization. If the initialization exits by
throwing an exception, the initialization is not complete, so it will
be tried again the next time control enters the declaration. If
control enters the declaration concurrently while the variable is
being initialized, the concurrent execution shall wait for completion
of the initialization.
[…]

在C11之前,我们必须处理静态局部变量,就像处理任何其他关键部分一样.我们可以在C++ scoped static initialization is not thread-safe, on purpose!之后找到对C 11前的情况的精彩描述.

点赞