首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >静态变量初始化顺序

静态变量初始化顺序
EN

Stack Overflow用户
提问于 2008-10-17 06:43:31
回答 5查看 79.6K关注 0票数 68

C++保证编译单元(.cpp文件)中的变量按照声明的顺序进行初始化。对于编译单元的数量,这个规则对每个编译单元单独起作用(我指的是类外的静态变量)。

但是,变量的初始化顺序在不同的编译单元中是未定义的。

我在哪里可以看到关于这个订单的一些解释,关于gcc和MSVC (我知道依赖于这是一个非常糟糕的想法-它只是为了理解我们在迁移到新的GCC主要和不同的操作系统时可能会遇到的遗留代码的问题)?

EN

回答 5

Stack Overflow用户

发布于 2008-10-17 07:30:17

我希望模块之间的构造函数顺序主要取决于将对象传递给链接器的顺序。

但是,GCC确实允许您为全局ctor执行use init_priority to explicitly specify the ordering

代码语言:javascript
复制
class Thingy
{
public:
    Thingy(char*p) {printf(p);}
};

Thingy a("A");
Thingy b("B");
Thingy c("C");

输出'ABC‘正如你所期望的,但是

代码语言:javascript
复制
Thingy a __attribute__((init_priority(300))) ("A");
Thingy b __attribute__((init_priority(200))) ("B");
Thingy c __attribute__((init_priority(400))) ("C");

输出'BAC‘。

票数 20
EN

Stack Overflow用户

发布于 2008-10-17 07:41:03

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 -此链接会移动。这个one更稳定,但你得四处看看。

编辑: osgx提供了更好的link

票数 4
EN

Stack Overflow用户

发布于 2020-07-14 21:29:00

一个健壮的解决方案是使用一个getter函数,该函数返回对静态变量的引用。下面显示了一个简单的示例,它是我们的SDG Controller middleware中的一个复杂变体。

代码语言:javascript
复制
// Foo.h
class Foo {
 public:
  Foo() {}

  static bool insertIntoBar(int number);

 private:
  static std::vector<int>& getBar();
};

// Foo.cpp
std::vector<int>& Foo::getBar() {
  static std::vector<int> bar;
  return bar;
}

bool Foo::insertIntoBar(int number) {
  getBar().push_back(number);
  return true;
}

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

 private:
  static bool a1;
};

// A.cpp
bool A::a1 = Foo::insertIntoBar(22);

初始化将使用唯一的静态成员变量bool A::a1。这将调用Foo::insertIntoBar(22)。这将调用Foo::getBar(),在返回对已初始化对象的引用之前,将进行静态std::vector<int>变量的初始化。

如果static std::vector<int> bar直接作为Foo class的成员变量,则根据源文件的命名顺序,可能会在调用insertIntoBar()之后初始化bar,从而使程序崩溃。

如果多个静态成员变量在初始化期间调用insertIntoBar(),则顺序将不依赖于源文件的名称,也就是随机的,但将确保在将任何值插入到std::vector<int>之前对其进行初始化。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/211237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档