編譯程序時缴罗,編譯器報錯
error: jump to case label [-fpermissive] 乘综, error: crosses initialization of 'xxxx'
,對相關內(nèi)容進行簡單的梳理
一趴捅、問題代碼
int main()
{
int test = 2;
switch(test)
{
case 1:
int i = 1; // i初始化后垫毙,一直存在,直到switch結束
cout << i;
break;
case 2:
cout << i; // i未被初始化
break;
default:
cout << "error" << endl;
}
}
#報錯信息如下
//test.cpp: In function 'int main()':
//test.cpp: error: jump to case label [-fpermissive]
// case 2:
// ^
//test.cpp: error: crosses initialization of 'int i'
// int b = 1;
//test.cpp: error: jump to case label [-fpermissive]
// default:
// ^
//test.cpp:11:8: error: crosses initialization of 'int i'
// int b = 1;
二拱绑、說明
從上面的代碼中可以看出综芥,因為switch中沒有單獨的區(qū)域塊來限定變量i的聲明周期,所以變量的作用域是初始化點到switch的結尾處猎拨。這里由于我們無法確定其他case中是否會使用到這種變量膀藐,使用之前變量是否被初始化,所以編譯器會報錯红省。例如:test值為2额各,直接執(zhí)行case 2的話,未定義變量就會出異常吧恃。這也是編譯器報錯crosses initialization
的原因虾啦。
經(jīng)過檢驗發(fā)現(xiàn),無論其他分支是否包含定義的變量痕寓,只要case中帶變量不帶括號傲醉,編譯器都會報錯
。
int main()
{
int test = 2;
switch(test)
{
case 1:
int i = 1;
cout << i;
break;
case 2:
cout << 3; // 同樣會報錯
break;
default:
cout << "error" << endl;
}
}
#報錯信息如下
//test.cpp: In function 'int main()':
//test.cpp: error: jump to case label [-fpermissive]
// case 2:
// ^
//test.cpp: error: crosses initialization of 'int i'
// int i = 1;
//test.cpp: error: jump to case label [-fpermissive]
// default:
// ^
//test.cpp: error: crosses initialization of 'int i'
// int i = 1;
三呻率、修改方法
1硬毕、【縮小作用域】將case 1的代碼用{ }括起來,設定清楚變量i的作用域筷凤,避免其他case訪問
2昭殉、【擴大作用域】將變量i放到switch外部,switch中的每個case都可以訪問
四藐守、深入了解
switch語句是goto語句的一種挪丢,所以goto具備相同的性質(zhì),下述的goto語句不會被執(zhí)行卢厂,變量i一定會被定義乾蓬,但是會報跟上面一樣的錯誤。這說明goto與標簽之間慎恒,不能出現(xiàn)變量任内。變量必須出現(xiàn)在goto之前或標簽之后撵渡。
int main()
{
if(0)
{
goto end;
}
int i = 1;
end:
cout << i;
}
#報錯信息如下:
//test.cpp: In function 'int main()':
//test.cpp error: jump to label 'end' [-fpermissive]
// end:
// ^
//test.cpp error: from here [-fpermissive]
// goto end;
// ^
//test.cpp: error: crosses initialization of 'int i'
// int i = 1;
上述例子,將變量的初始化放在goto標簽之前死嗦,或者end標簽之后趋距,都是可以的