【C++ 異?!縠rror: jump to case label [-fpermissive]

編譯程序時(shí),編譯器報(bào)錯(cuò)error: jump to case label [-fpermissive] , error: crosses initialization of 'xxxx',對相關(guān)內(nèi)容進(jìn)行簡單的梳理

一、問題代碼

int main()
{
  int test = 2;
  switch(test)
  {
    case 1:
      int i = 1;  // i初始化后,一直存在,直到switch結(jié)束
      cout << i;
      break;
    case 2:
      cout << i;  // i未被初始化
      break;
    default:
      cout << "error" << endl;
  }
}
#報(bào)錯(cuò)信息如下
//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;

二、說明
從上面的代碼中可以看出,因?yàn)閟witch中沒有單獨(dú)的區(qū)域塊來限定變量i的聲明周期,所以變量的作用域是初始化點(diǎn)到switch的結(jié)尾處。這里由于我們無法確定其他case中是否會使用到這種變量,使用之前變量是否被初始化,所以編譯器會報(bào)錯(cuò)。例如:test值為2,直接執(zhí)行case 2的話,未定義變量就會出異常。這也是編譯器報(bào)錯(cuò)crosses initialization的原因。

經(jīng)過檢驗(yàn)發(fā)現(xiàn),無論其他分支是否包含定義的變量,只要case中帶變量不帶括號,編譯器都會報(bào)錯(cuò)

int main()
{
  int test = 2;
  switch(test)
  {
    case 1:
      int i = 1; 
      cout << i;  
      break;
    case 2:
      cout << 3; // 同樣會報(bào)錯(cuò)
      break;
    default:
      cout << "error" << endl;
  }
}
#報(bào)錯(cuò)信息如下
//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的代碼用{ }括起來,設(shè)定清楚變量i的作用域,避免其他case訪問
2、【擴(kuò)大作用域】將變量i放到switch外部,switch中的每個(gè)case都可以訪問

四、深入了解
switch語句是goto語句的一種,所以goto具備相同的性質(zhì),下述的goto語句不會被執(zhí)行,變量i一定會被定義,但是會報(bào)跟上面一樣的錯(cuò)誤。這說明goto與標(biāo)簽之間,不能出現(xiàn)變量。變量必須出現(xiàn)在goto之前或標(biāo)簽之后。

int main()
{
    if(0)
    {
        goto end;
    }

    int i = 1;

    end:
       cout << i;
}
#報(bào)錯(cuò)信息如下:
//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標(biāo)簽之前,或者end標(biāo)簽之后,都是可以的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容