switch 內部的變量定義:
1 int i = 1; 2 switch(i) 3 { 4 case 0: 5 string str; //error 6 int val1 = 0; //error 7 int val2; //right 8 int val3; val3 = 0; //right 9 case 1: 10 val2 = 9; 11 cout << val2 << endl; 12 }
《C++ Primer》 P163: 如果在某處一個帶有初始值的變量位於作用域之外,在另一處該變量位於作用域之內,則從前一處跳轉到后一處的行為是非法行為。
在上面的代碼中line 5、6是錯誤的,line 7、8是沒問題的。
首先要明確的是,對於line 5、6、7、8中的變量來說,整個switch語句的{}內的聲明之后的范圍都是可見的。case語句不構成獨立的作用域,即在case 0:下定義的val2,在case 1下也是可見的(紅色字體貌似有問題)。
但是line5、6是錯誤的,因為在5、6兩行都在聲明變量時對變量進行了初始化(line 5 調用了默認的初始化函數),如果跳過此代碼,則可能會產生不可意料的錯誤,編譯器會報錯。line 7、8是正確的,因為在聲明的時候並沒有對變量初始化。
(如果有初始化,那么后面的代碼可以直接使用,但是如果跳過了初始化編譯器就會認為會發生不可預料的錯誤進而報錯。如果沒有初始化,則編譯器不會因為跳過此語句而報錯,因為你本來就沒有初始化並且這是c/c++允許的,比如在函數中的int a;就是一個未初始化的變量)
所以,不可以跳過帶初始值的變量(同一個作用域之內)。 在goto語句中同理:
1 int i = 1; 2 goto case_1; 3 4 case_0: 5 int val1; //right 6 int val2 = 9; //error 7 case_1: 8 val1 = 9; 9 val2 = 10;
test_scope.cpp: In function ‘int main(int, char**)’: test_scope.cpp:7: error: jump to label ‘case_1’ test_scope.cpp:2: error: from here test_scope.cpp:6: error: crosses initialization of ‘int val2’ (跳過了val2的初始化)