在给定的翻译单元中,文件级静态变量的顺序是否始终相同?
我有一个程序分为两个源文件:
example.cpp
#include <iostream>
class A {
public:
A(int x) {
::std::cout << "In A(" << x << ")\n";
}
};
static A first(1);
static A second(2);
example__main.cpp
int main(int argc, const char *argv[])
{
return 0;
}
该程序的输出保证为:
In A(1)
In A(2)
在所有平台和编译器上?如果是这样,标准中哪里有这样的规定?如果我使用命名空间并且 first
和 second
出现在不同的命名空间中,这有什么关系吗?如果它们不是静态的并且我使用的是匿名命名空间怎么办?
I have a program split up into two source files:
example.cpp
#include <iostream>
class A {
public:
A(int x) {
::std::cout << "In A(" << x << ")\n";
}
};
static A first(1);
static A second(2);
example__main.cpp
int main(int argc, const char *argv[])
{
return 0;
}
Is the output of this program guaranteed to be:
In A(1)
In A(2)
on all platforms and compilers? If so, where in the standard does it say this? Does it matter if I'm using namespaces and first
and second
appear in different namespaces? How about if they aren't static and I'm using an anonymous namespace?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,如果声明出现在同一翻译单元中,则为非局部静态对象定义初始化顺序。
从 C++03 开始,
Yes, the order of initialization is defined for non-local static objects if the declarations appear in the same translation unit.
From C++03,
在一个翻译单元内,全局变量分几个阶段进行初始化:
首先,所有具有“静态初始化”的变量都按照其声明顺序进行初始化(见下文)。
然后,再次按照声明的顺序执行所有“有序动态初始化”。
还有“无序动态初始化”,相对于其他动态初始化是“无序的”(但总是在静态初始化之后)。
静态和有序动态初始化的全局变量的销毁以相反的顺序进行(无序的全局变量再次“无序”,但在静态全局变量之前)。 TU 之间的相对初始化顺序未指定。
松散地解释术语:如果全局变量被初始化为常量(对于构造函数调用,这需要
constexpr
构造函数),或者如果它没有初始化程序并且已声明,则该全局变量是“静态初始化”的static
(使其零初始化):static int a; Foo b(1, true, Blue);
另一方面,如果初始化器不是任何“常量”,例如函数调用或非 constexpr 构造函数,则该对象是“动态初始化”的。大多数动态初始化的普通全局变量都是“有序的”;唯一的“无序”成员是模板专业化的静态成员等。(请注意,所有这些在 C++11 中都变得更加详细,因为现在明确关注线程本地存储和线程启动时的初始化。)
Within one translation unit, global variables are initialized in several stages:
First, all variables that have "static initialization" are initialized in their order of declaration (see below).
Then, all "ordered dynamic initializations" are performed, again in their order of declaration.
There are also "unordered dynamic initializations", which are "unsequenced" with respect to the other dynamic initializations (but always after the static ones).
Destruction of statically and ordered-dynamically initialized globals proceeds in opposite order (and the unordered ones again "unsequenced", but before the static ones). The relative initialization ordering across TUs is unspecified.
To explain the terminology loosely: a global variable is "statically initialized" if it is either initialized to a constant (for constructor calls, this requires
constexpr
constructors), or if it is has no initializer and is declaredstatic
(which makes it zero-initialized):static int a; Foo b(1, true, Blue);
On the other hand, if the initializer is not anything "constant", like a function call or a non-constexpr constructor, then the object is "dynamically initialized". Most ordinary globals that are dynamically initialized are "ordered"; the only "unordered" ones are static members of template specializations and such like.(Note that all this got a lot more detailed in C++11, as there is now explicit attention to thread-local storage and initialization at the start of a thread.)