是什么让静态变量只初始化一次?
我注意到如果你在代码中用 C++ 初始化一个静态变量,初始化只会在你第一次运行函数时运行.
I noticed that if you initialize a static variable in C++ in code, the initialization only runs the first time you run the function.
这很酷,但它是如何实现的?它是否转化为某种扭曲的 if 语句?(如果给定值,则..)
That is cool, but how is that implemented? Does it translate to some kind of twisted if statement? (if given a value, then ..)
void go( int x )
{
static int j = x ;
cout << ++j << endl ; // see 6, 7, 8
}
int main()
{
go( 5 ) ;
go( 5 ) ;
go( 5 ) ;
}
推荐答案
是的,它通常会转换为带有内部布尔标志的隐式 if
语句.因此,在最基本的实现中,您的声明通常会转换为类似
Yes, it does normally translate into an implicit if
statement with an internal boolean flag. So, in the most basic implementation your declaration normally translates into something like
void go( int x ) {
static int j;
static bool j_initialized;
if (!j_initialized) {
j = x;
j_initialized = true;
}
...
}
最重要的是,如果您的静态对象具有非平凡的析构函数,则语言必须遵守另一条规则:此类静态对象必须以其构造的相反顺序进行析构.由于构造顺序仅在运行时已知,因此销毁顺序也在运行时定义.所以,每次你用非平凡的析构函数构造一个局部静态对象时,程序都必须将它注册到某种线性容器中,稍后它将用来以适当的顺序析构这些对象.
On top of that, if your static object has a non-trivial destructor, the language has to obey another rule: such static objects have to be destructed in the reverse order of their construction. Since the construction order is only known at run-time, the destruction order becomes defined at run-time as well. So, every time you construct a local static object with non-trivial destructor, the program has to register it in some kind of linear container, which it will later use to destruct these objects in proper order.
不用说,实际细节取决于实现.
Needless to say, the actual details depend on implementation.
值得补充的是,当涉及使用编译时常量初始化的原始"类型的静态对象(如您的示例中的 int
)时,编译器可以在启动时自由地初始化该对象.你永远不会注意到差异.但是,如果您使用非原始"对象来举一个更复杂的示例
It is worth adding that when it comes to static objects of "primitive" types (like int
in your example) initialized with compile-time constants, the compiler is free to initialize that object at startup. You will never notice the difference. However, if you take a more complicated example with a "non-primitive" object
void go( int x ) {
static std::string s = "Hello World!";
...
那么上述带有 if
的方法是您应该期望在生成的代码中找到的,即使对象是用编译时常量初始化的.
then the above approach with if
is what you should expect to find in the generated code even when the object is initialized with a compile-time constant.
在您的情况下,初始化程序在编译时未知,这意味着编译器必须延迟初始化并使用隐式 if
.
In your case the initializer is not known at compile time, which means that the compiler has to delay the initialization and use that implicit if
.
相关文章