如何处理clang中的全局构造函数警告?

Wal*_*ter 24 c++ clang

Clang警告(当使用-Weverything或时Wglobal-constructors)关于静态对象的构造函数.

warning: declaration requires a global constructor
      [-Wglobal-constructors]
A A::my_A; // triggers said warning
     ^~~~
Run Code Online (Sandbox Code Playgroud)

为什么这是相关的,应该如何处理这个警告?

简单示例代码:

class A {
  // ...
  static A my_A;
  A();
};

A A::my_A; // triggers said warning
Run Code Online (Sandbox Code Playgroud)

How*_*ant 22

这是一个更简单的情况,触发相同的警告:

class A {
public:
  // ...
  A();
};

A my_A; // triggers said warning


test.cpp:7:3: warning: declaration requires a global constructor [-Wglobal-constructors]
A my_A; // triggers said warning
  ^~~~
1 warning generated.
Run Code Online (Sandbox Code Playgroud)

这是完全合法且安全的C++.

但是,对于您拥有的每个非平凡的全局构造函数,应用程序的启动时间都会受到影响.该警告只是让您了解此潜在性能问题的一种方式.

您可以使用-Wno-global-constructors禁用警告.或者您可以更改为这样的延迟初始化方案:

A&
my_A()
{
    static A a;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

这完全避免了这个问题(并且抑制了警告).

  • 你确定性能是主要问题吗?我认为可能出现更大的问题 - 因为全局/静态初始化的顺序在C++中是未定义的,非平凡的全局对象可能在其构造函数中引入对另一个全局对象的依赖,从而导致未定义的行为. (16认同)
  • @icepack:是的,我确定。全局构造函数的顺序是部分定义的。出现在同一个翻译单元中的那些构造函数是按照出现的顺序构造的。未指定翻译单元之间的排序。是的,这可能会导致问题。但是不,这不是引入此警告的动机。 (3认同)
  • 好的谢谢。我想我对*全局构造函数* 的措辞感到困惑。也许像*启动时构建*这样的东西更合适。 (2认同)

Max*_*kin 5

来自@Howard Hinnant的解决方案避免使用全局构造函数,但它仍然会退出析构函数.它可以选择-Wexit-time-destructors

所以理想的解决方案可以基于http://src.chromium.org/svn/trunk/src/base/basictypes.h中的 CR_DEFINE_STATIC_LOCAL.

A& my_A()
{
    static A &a = *new A;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

  • 此代码将从内存泄漏工具创建警告. (2认同)