2008-12-01 82 views
4

我一直在使用匿名命名空間來存儲本地數據和函數,並想知道數據何時被初始化?應用程序何時以與靜態數據相同的方式啓動,還是依賴於編譯器?例如:什麼時候匿名命名空間數據被初始化?

// foo.cpp 
#include "foo.h" 

namespace { 

const int SOME_VALUE = 42; 

} 

void foo::SomeFunc(int n) 
{ 
    if (n == SOME_VALUE) 
    { 
     ... 
    } 
} 

問題出現在某些代碼是線程安全的。在上面的例子中,我需要確定SOME_VALUE是在第一次調用SomeFunc之前初始化的。

回答

6

C++標準,3.6.2/1

零初始化和 初始化以恆定 表達式統稱 靜態初始化;其他所有 初始化都是動態的 初始化。 POD類型對象 (3.9)靜態存儲持續時間 使用常量表達式 (5.19)初始化應在任何 動態初始化發生之前初始化。 對象與同一 翻譯單元中命名空間範圍定義的靜態存儲持續時間 和動態 初始化應 ,其中它們的定義 出現在翻譯單元的次序進行初始化。

這實際上意味着,即使其他翻譯單元調用外部您SomeFunc功能,您SOME_VALUE恆將始終正確初始化,因爲它有常量表達式初始化。

函數在main(main之前)被調用的唯一方法是在初始化具有動態初始化的對象時。但到那時,根據標準報價,您的POD變量的初始化已經完成。

2

在這種特殊情況下(全局變量是const),變量在編譯時被「初始化」。

SOME_VALUE總是等於42

事實上,大多數(?全部)編譯器將實際編譯這個就好像是硬編碼:

void foo::SomeFunc(int n) 
{ 
    if (n == 42) 
    { 
     ... 
    } 
} 
0

爲正確答案您的實際問題看Mathieu的回答。

但是請注意,匿名命名空間不會影響全局對象和/或靜態對象的生命週期的開始和結束。換句話說,就像使用普通的舊的全局變量一樣,你也容易受到static initialization order問題的影響。

該鏈接還提供了一些關於避免該問題的提示,在下一個主題中使用「首次使用時的構造」。

1

命名空間與初始化時間無關。名稱空間所做的就是更改屬於它的名稱。

相關問題