在C++

2013-04-15 16 views
14

全局對象和atexit對破壞之間的順序我不知道,可以用C確保全局對象的破壞和atexit之間爲了++在C++

我有一個全局對象和註冊atexit功能象下面這樣:

static MyClass g_class; 

void onExit() 
{ 
    // do some destruction 
} 

int main() 
{ 
    atexit(onExit); 

    return 0; 
} 

我發現在Visual Studio 2012和gcc4.7.2中的MyClass::~MyClass()之前調用onExit()。我確定總是在全局對象(如g_class)銷燬之前調用onExit

我想知道全局對象註冊順序和atexit註冊順序使用相同的順序表。 或者全局對象順序和atexit命令之間沒有關係?

修改:抱歉,我寫了一個錯誤。整理示例代碼時我很困惑。在〜MyClass()之前調用onExit()

+0

我懷疑訂單不是100%肯定要定義的。你爲什麼在乎? –

+0

在'MyClass'之前創建另一個全局對象,並在其構造函數中調用'atexit(onExit)'來檢查。 – lapk

+1

想要控制對象的生命週期,使用動態的對象。 – PiotrNycz

回答

14

更新:OP做了一些混淆,看來VC11確實的行爲如C++ 11標準所規定的那樣。下面的答案是在沒有的假設下編寫的。

因此,這個問題的答案:

我是肯定onExit是全球性的物品(如g_class)破壞之前一直運行?

「是」,只要你是一個完全兼容的編譯工作。


我發現MyClass::~MyClass()onExit()之前在Visual Studio 2012

如果是這樣的情況下調用,那麼它是一個錯誤 VC11。每一段中的C++ 11標準的3.6.3/1:

析構函數(12.4),用於初始化的對象(即,對象,其壽命(3.8)已經開始)具有靜態存儲 持續時間被稱爲作爲從main返回的結果以及std::exit(18.5)的呼叫結果。 [...]

此外,每段落3.6.3/3:

如果具有靜態存儲持續時間的對象的初始化的完成呼叫之前測序 到std::atexit(見<cstdlib>,18.5),調用傳遞給函數std::atexit的函數在調用對象的析構函數之前被排序。

因此,你的情況,onexit()應的MyClass析構函數調用之前。

據我所知,Clang 3.2和GCC 4.8.0在這方面是兼容的,如live example所示。

+0

g ++是否兼容取決於編譯器選項和平臺。 (它可以符合要求,但由於在許多平臺上,'atexit'功能由平臺提供,所以並不總是合理可行。) –

+0

對不起。我寫了一個錯誤。 onexit()在〜MyClass之前被調用。整理示例代碼時,我感到非常困惑。 – zelon

+2

@zelon:好的。那麼行爲是正確的,這就是C++標準指定的。 –