首頁  >  文章  >  後端開發  >  如何保證C中具有依賴關係的全域變數的正確初始化?

如何保證C中具有依賴關係的全域變數的正確初始化?

Linda Hamilton
Linda Hamilton原創
2024-11-03 22:56:02633瀏覽

 How to Guarantee Proper Initialization of Global Variables in C   with Dependencies?

C 全域初始化順序:探索相依性

在 C 中,翻譯單元中的全域變數通常會依照宣告的順序進行初始化。但是,在考慮跨多個翻譯單元的初始化順序時,可能會出現混亂。

初始問題場景

考慮以下程式碼:

<code class="cpp">struct Foo {
    Foo() { printf("Foo::Foo()\n"); }
    void add() { printf("Foo::add()\n"); }
    static int addToGlobal() {
        globalFoo.add();
        return 0;
    }
};

Foo globalFoo;

int dummy = Foo::addToGlobal();

int main() { printf("main()\n"); return 0; }</code>

與這段程式碼,預期的輸出是:

Foo::Foo()
Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
main()

但是,交換dummy 和globalFoo 的宣告和初始化會產生不同的輸出:

Foo::addToGlobal() START
Foo::add()
Foo::addToGlobal() END
Foo::Foo()
main()

初始化順序和依賴關係

此行為顯示全域變數的初始化順序忽略了依賴關係。在這種情況下,對 Foo::addToGlobal() 的呼叫嘗試在呼叫其建構函式之前存取 Foo 的方法。

解決方案:確保正確的初始化

為了確保Foo 的構造函數在dummy 初始化之前被調用,我們可以在同一翻譯單元中在dummy 之前定義globalFoo 。這保證了 globalFoo 將首先被初始化,從而允許 addToGlobal() 成功存取其方法。

替代解決方案:靜態初始化守衛

或者,我們可以引入靜態Foo::addToGlobal() 內的初始化保護:

<code class="cpp">static Foo* pFoo = nullptr;

if (pFoo == nullptr) {
    pFoo = &globalFoo;
}

pFoo->add();</code>

此檢查確保指標pFoo 在存取其方法之前已初始化為globalFoo,有效防止過早使用globalFoo。

以上是如何保證C中具有依賴關係的全域變數的正確初始化?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn