2013-06-18 81 views
0

從這個FAQ:What are Aggregates and PODs and how/why are they special?吊艙和規則轉到

我們有這樣的一部分:

goto語句。正如你所知道的,它是非法的(編譯器應該發出一個錯誤),通過goto從某個變量尚未處於範圍內的點跳轉到已經處於範圍內的點。此限制僅適用於變量爲非POD類型的情況。在下面的例子中,f()是格式不正確的,而g()是格式良好的。請注意,Microsoft編譯器對此規則過於自由 - 只是在這兩種情況下發出警告。

int f() { 
    struct NonPOD { NonPOD(){}}; 
    goto label; 
    NonPOD x; 
label: 
    return 0; 
} 

int g(){ 
    struct POD {int i; char c;}; 
    goto label; 
    POD x; 
label: 
    return 0; 
} 

我想了解爲什麼區別?它似乎可能是,即使POD是 goto後宣佈它已經初始化,沒有更多的需要做,而非POD未被初始化的 。還是我吠叫錯了樹?

回答

1

轉到不能跳過初始化,除非它出現在一個塊中,並且您跳過整個塊。

對於non-POD,調用ctor。這是必要的,並且必須在變量出現的地方發生。如果你可以跳過它,那麼這個變量就會被打破。最終它的計劃將會爆炸。

+0

所以這意味着在POD情況下初始化已經完成,但在非POD的情況下,它還沒有完成。 –

+0

POD不能有ctor - 這是要求之一,但我認爲如果你使用{} init,也會失敗。 –

+0

那麼,構造函數是隱含的,它必須在某個點運行。 goto不能跳過初始化,所以POD必須已經初始化。我試圖弄清楚什麼時候會發生。 –

1

f的情況下,x析構函數(其由編譯器自動在具有構造爲由設置,從而使struct非POD型)將被稱爲「在返回」。對未構造的對象調用析構函數並不是一個好計劃。如果我們讓這個代碼更復雜一些,那麼我們很容易就會在編譯器非常複雜的情況下知道哪些對象已經被初始化,哪些沒有被初始化,所以只是簡單地禁止跳過任何初始化(使用switch語句來,其中某些對象每種情況下內導入時的該另一個常見的情況是:

switch(x) 
{ 
    case 1: 
     NonPod x; 
     .. 
     break; 
    case 2: 
     ... 
} 

是一個類似的構建體(和同樣不好)

+0

所以POD已經被初始化了,goto可以跳過它。 POD是什麼時候初始化的? –