2016-09-24 119 views
2

我在玩代碼時遇到了一個有趣的特性。我正在使用Eclipse CDT 4.5.2,並啓用了Cygwin和C++ 14(-std = C++ 14)。中箱的變量初始化通常是禁止的,但下面的代碼編譯:SWITCH語句中DEFAULT後CASE中的C++變量初始化

switch(int switchStatement = 11) 
{ 
    default: 
     ++j; 
     break; // break is optional, still compiles even if omitted 
    case 11: 
     int caseVariable = 0; 
     ++j; 
} 

如果添加另一種情況是,那麼除了「跳轉到case標籤」被提升。

switch(int switchStatement = 11) 
{ 
    default: 
     ++j; 
    case 11: 
     int caseVariable = 0; 
     ++j; 
    case 12: // exception 
     ++j; 
} 

有人可以解釋我是如何工作的嗎?

+0

重新打開:dupe沒有解釋其中一個片段的編譯成功。 (我認爲這是一個編譯器錯誤。) – Bathsheba

+0

它不工作,如果你添加一個休息到案件11? –

+0

只有當變量聲明在最後一個'case'塊中時它才起作用嗎? –

回答

1

爲什麼在第二種情況下出現錯誤,但在最後一種情況下聲明變量時沒有出錯?

因爲C++的規則是跳轉無法通過同一範圍內的變量 聲明。所以當你跳轉到第二種情況時,你會在情況1中通過 變量聲明。但是 最後一種情況下的變量聲明是可以的,因爲它永遠不會被跳過。

規則的原因是,如果允許跳過變量 聲明,那麼編譯器將很難確定是否調用該變量的析構函數 。如果你已經跳過了 變量聲明,那麼你不需要調用析構函數,如果你沒有跳過,那麼你會這樣做。

在一個case語句中聲明和初始化的變量在其他情況下仍然可見,但由於初始化代碼屬於另一個case,所以它們不會被初始化。

在C++問題的範圍。這裏,case語句是「標籤」。因此,編譯器會將它們視爲從一個語句跳到另一個語句。在這個特定的例子中,編譯器不會理解如何進一步處理。要解決此問題,您可以將案例中的代碼包含到{}塊中。額外的{和}表示編譯器在調用析構函數時沒有任何問題。因此,在聲明新變量時爲該特定情況聲明提供範圍或大括號很重要。

+0

你爲什麼發佈你的答案兩次?你可以隨時編輯。 –

+0

錯誤,這就是爲什麼我刪除第二篇文章 –