50

在我的 C++11 代码中,我在以下情况下收到 clang 警告“声明需要退出时析构函数”:

static const std::map<int, const someStruct> mymap = {
    {1, {
        "A",
        "B",
        "C"
    }},
    {2, {
        "D",
        "E",
        "F"
    }}
};

据我了解,谷歌需要一个“退出时间析构函数”来以一种确定的方式销毁 main() 和静态变量,以防止由于“已经发布的变量”而导致退出时崩溃。是对的吗?有人可以更好地解释吗?

另外:我该怎么办(我不想禁用警告)?上面的代码仅在一个线程的上下文中使用。

看起来这就是 Chromium 处理这些情况的方式;这也是我的情况的正确方法吗?

#define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \
  static type& name = *new type arguments

(来源:https ://chromium.googlesource.com/chromium/src/+/32352ad08ee673a4d43e8593ce988b224f6482d3/base/basictypes.h )

4

2 回答 2

27

全局和函数静态对象将在您的应用程序退出时调用它们的析构函数。这些析构函数是“退出时间析构函数”。并以与它们构建时相反的顺序被调用。

正如您所说,如果其中一些析构函数接触到已经销毁的对象,您的程序可能会崩溃。此外,在退出时运行的析构函数会使程序退出速度变慢,并且大多数情况下它们对于程序的正确性不是必需的(因为当程序退出时,它无论如何都会释放其所有内存)。

警告只是指出您有将在退出时运行的析构函数。

您提出的修复将堆分配对象,这不会导致它在程序退出时自动销毁。对于您的情况,这可能已经足够了。

于 2013-01-15T10:27:27.680 回答
3

请参阅属性 no_destroy/always_destroy https://clang.llvm.org/docs/AttributeReference.html

于 2021-02-10T13:34:07.683 回答