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

C++ 如何处理clang中的全局构造函数警告?,c++,clang,C++,Clang,Clang警告(当使用-Weverything或Wglobal构造函数时)静态对象的构造函数 warning: declaration requires a global constructor [-Wglobal-constructors] A A::my_A; // triggers said warning ^~~~ 为什么这是相关的,人们应该如何处理这一警告 简单示例代码: class A { // ... static A my_A; A(); };

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

warning: declaration requires a global constructor
      [-Wglobal-constructors]
A A::my_A; // triggers said warning
     ^~~~
为什么这是相关的,人们应该如何处理这一警告

简单示例代码:

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

A A::my_A; // triggers said warning

下面是一个触发相同警告的简单案例:

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.

这是完全合法和安全的C++。 然而,对于您拥有的每个非平凡的全局构造函数,应用程序的启动时间都会受到影响。警告只是让您了解此潜在性能问题的一种方式

可以使用-Wno全局构造函数禁用警告。或者,您可以更改为如下所示的延迟初始化方案:

A&
my_A()
{
    static A a;
    return a;
}

它完全避免了问题(并抑制了警告)。

来自@Howard Hinnant的解决方案避免了全局构造函数,但它仍然会退出时间析构函数。 可以通过选项
-Wexit time析构函数找到它

因此,理想的解决方案可以基于CR_DEFINE_STATIC_LOCAL from


我们能看到警告吗?这是在一个.h文件中吗?@user93353否。它是
静态的
。它在
类A
中声明,但它不在每个
类A
@DrewDormann中-此程序编译
结构A{static A s;};A::s;S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.S.,这几乎就像一个C++笑话。为什么有人希望在其内部有一个静态对象?@user93353 a
static
对象是
类的一部分,而不是类的单个对象的一部分,即不在其内部。尽管如此,您可以像访问对象的成员一样访问它:
a::s
a()。s
引用同一(且仅)对象(无论该对象是否属于同一类型
a
)。拥有相同类型的
静态成员是实现单例的一种方法。您确定性能是主要问题吗?我认为更大的问题可能会出现——因为全局/静态顺序初始化在C++中是不确定的,非平凡的全局对象可能会在其构造函数中引入另一个全局对象的依赖性,导致未定义的行为。我想我被全局构造函数的措辞弄糊涂了。也许像在启动时构建这样的东西更合适。这确实可能发生在我的代码中,尽管我从未遇到过问题…@icepack:是的,我确定。全局构造函数的顺序是部分定义的。出现在同一翻译单元中的那些构造器是按照出现的顺序构造的。未指定翻译单位之间的顺序。是的,这会引起问题。但不,这不是引入此警告的动机。如果clang/gcc能够告诉您除了如何全局禁用警告之外,如何抑制某个特定呼叫站点的警告,那就太好了。我经常发现抑制单个呼叫站点是非常不习惯的,并且在不同的情况下差异很大。这个小技巧让我解决了这个问题,谢谢。这段代码将从内存泄漏工具中创建警告。当然!不会为此代码调用析构函数。@DavidFare在
a::my_a()
?@Walter:定义{static a a a;return a;}将给出与您建议的unique相同的结果_ptr@hauron中介绍了Speakus提出的解决方案与使用静态对象不同的原因。一个更好但更复杂的解决方案(由FAQ调用)缺少解释,但我想这是指用于初始化
std::cout
和friends的技术(请参阅)。
A& my_A()
{
    static A &a = *new A;
    return a;
}