5

我有一个程序分成两个源文件:

例子.cpp

#include <iostream>

class A {
 public:
   A(int x) {
      ::std::cout << "In A(" << x << ")\n";
   }
};

static A first(1);
static A second(2);

示例__ main.cpp

int main(int argc, const char *argv[])
{
   return 0;
}

该程序的输出是否保证为:

In A(1)
In A(2)

在所有平台和编译器上?如果是这样,它在标准中的什么地方这么说?如果我使用命名空间firstsecond出现在不同的命名空间中,这有关系吗?如果它们不是静态的并且我使用的是匿名命名空间呢?

4

2 回答 2

5

是的,如果声明出现在同一个翻译单元中,则为非本地静态对象定义初始化顺序。

从 C++03 开始​​,

(3.6/2) 在同一翻译单元的命名空间范围内定义的静态存储持续时间并动态初始化的对象应按照其定义在翻译单元中出现的顺序进行初始化。[注:8.5.1 描述了聚合成员的初始化顺序。局部静态对象的初始化在 6.7 中描述。]

于 2011-11-10T23:40:01.460 回答
3

在一个翻译单元中,全局变量分几个阶段进行初始化:

  • 首先,所有具有“静态初始化”的变量都按照它们的声明顺序进行初始化(见下文)。

  • 然后,再次按照它们的声明顺序执行所有“有序动态初始化”。

  • 还有“无序的动态初始化”,它们相对于其他动态初始化是“无序的”(但总是在静态初始化之后)。

静态和有序动态初始化的全局变量的破坏以相反的顺序进行(无序的再次“无序”,但在静态之前)。未指定跨 TU 的相对初始化顺序。

constexpr松散地解释术语:如果全局变量被初始化为常量(对于构造函数调用,这需要构造函数),或者如果它没有初始化程序并被声明static(这使其零初始化) ,则它是“静态初始化的” :static int a; Foo b(1, true, Blue);另一方面,如果初始值设定项不是任何“常量”,例如函数调用或非 constexpr 构造函数,则该对象是“动态初始化的”。大多数动态初始化的普通全局变量都是“有序的”;唯一的“无序”是模板特化等的静态成员。

(请注意,所有这些都在 C++11 中得到了更详细的说明,因为现在明确关注线程本地存储和线程开始时的初始化。)

于 2011-11-10T23:28:39.193 回答