一千萬個為什麽

搜索

編譯器如何實現靜態變量初始化?

我很好奇函數中靜態變量的底層實現。

如果我聲明一個基本類型(char,int,double等)的靜態變量並給它一個初始值,我想象編譯器只是在程序的最開始處設置該變量的值> main()被調用:

void SomeFunction();

int main(int argCount, char ** argList)
{
   //at this point, the memory reserved for 'answer'
   //already contains the value of 42
    SomeFunction();
}

void SomeFunction()
{
    static int answer = 42;
}

但是,如果靜態變量是一個類的實例:

class MyClass
{
    //...
};

void SomeFunction();

int main(int argCount, char ** argList)
{
    SomeFunction();
}

void SomeFunction()
{
    static MyClass myVar;
}

我知道在第一次調用該函數之前它不會被初始化。由於編譯器無法知道函數何時第一次被調用,它是如何產生這種行為的?它是否基本上將一個if塊引入函數體?

static bool initialized = 0;
if (!initialized)
{
   //construct myVar
    initialized = 1;
}

最佳答案

在我看到的編譯器輸出中,函數局部靜態變量的初始化完全如您所想。

請註意,通常這不是以線程安全的方式完成的。因此,如果你有像可能從多個線程調用的靜態局部函數那樣的功能,你應該考慮到這一點。在調用任何其他函數之前在主線程中調用該函數通常會起到訣竅的作用。

我應該補充一點,如果本地靜態的初始化是通過一個簡單的常量來實現的,那麽編譯器不需要經歷這些回轉 - 它可以只是初始化圖像中的變量或在 main()之前初始化變量。 就像一個常規的靜態初始化(因為你的程序無法區分)。但是如果你用一個函數的返回值對它進行初始化,那麽編譯器幾乎不得不測試一個標誌,指示初始化是否已經完成或者什麽等價。

轉載註明原文: 編譯器如何實現靜態變量初始化?