[英]local scope in switch case
我看到了一些令人驚訝的代碼:
#include <iostream>
using namespace std;
int main() {
// your code goes here
auto myDummy = [](int i){
switch(i){
case 0: return 0;
case 1:{
std::cout << "Evaluated 1\n";
if(i == 1){
return 1;
}
case 2:
std::cout << "Evaluated 2\n";
return 2;
}
break;
default: return -1;
}
};
std::cout << myDummy(1) << "\n";
return 0;
}
它在沒有警告的情況下編譯和運行。 案例1 {}的括號似乎被忽略了。
myDummy(1)
- > 1
myDummy(2)
- > 2
如果我將案例1的代碼修改為:
case 1:{
std::cout << "Evaluated 1\n";
int a = i;
if(a == 1){
return 1;
}
case 2:
std::cout << "Evaluated 2\n";
return 2;
}
break;
然后它不再編譯:
prog.cpp:16:13:錯誤:跳轉到案例標簽[-fpermissive]
case 2: ^ prog.cpp:12:21: note: crosses initialization of 'int a' int a = i;
案例1的括號:{}中斷; 不要取消開關上下文。 它只是為變量創建了一個局部范圍。 但這真的很混亂。 為什么這樣的行為呢?
這是標准關於switch
說法(§6.4.2,強調我的):
2 - switch語句中的任何語句都可以用一個或多個case標簽標記,如下所示:case constant-expression:其中constant-expression應該是switch類型的switch類型的轉換常量表達式(5.19)。
<...>
5 - 執行switch語句時,將評估其條件並與每個case常量進行比較。 如果其中一個case常量等於條件的值,則將控制權傳遞給匹配的case標簽后面的語句
因此, switch
並不關心具體情況,以下是有效的:
int main() {
int i = 0;
switch(i)
{
case 1:
{
case 2:
{
if(false)
{
case 0:
std::cout << "hello there!"; //yes it will print
}
}
}
}
return 0;
}
關於你提出的修改,請檢查我對這個問題的回答 。 基本上用
case 1:{
std::cout << "Evaluated 1\n";
int a = i;
if(a == 1){
return 1;
}
case 2:
//here a is in scope
std::cout << "Evaluated 2\n";
return 2;
}
您可以跳轉到case2
而不真正創建a
,但a
仍然會在范圍內。
您可以在任何地方放置范圍:
int main() {
int a;
{
int a; // in a more local scope.
}
}
但是你不能在一個范圍內放置一個變量初始化,它可以被超過2個開關的情況看到:
int main() {
int b;
switch(1) {
case 0:
int a = 0; // error
break;
case 1:
b = a; // what happens?
break;
}
}
最后,在另一個范圍內的案例標簽沒有任何問題(只要它不違反我們的第二個規則,那里):
int main() {
switch(1) {
case 1: {
break;
case 2:
break;
}
}
}
switch
到標簽的工作方式與移動到不同范圍塊時goto
標簽的方式相同。
在采用這樣的方案時應該小心,特別是在讀取未初始化的變量時,其行為是未定義的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.