問題描述
我注意到如果你在代碼中用 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
.
這篇關于是什么讓靜態變量只初始化一次?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!