【C++ 異常】error: jump to case label [-fpermissive]


編譯程序時,編譯器報錯error: jump to case label [-fpermissive] , error: crosses initialization of 'xxxx',對相關內容進行簡單的梳理

一、問題代碼

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中沒有單獨的區域塊來限定變量i的聲明周期,所以變量的作用域是初始化點到switch的結尾處。這里由於我們無法確定其他case中是否會使用到這種變量,使用之前變量是否被初始化,所以編譯器會報錯。例如:test值為2,直接執行case 2的話,未定義變量就會出異常。這也是編譯器報錯crosses initialization的原因。

經過檢驗發現,無論其他分支是否包含定義的變量,只要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具備相同的性質,下述的goto語句不會被執行,變量i一定會被定義,但是會報跟上面一樣的錯誤。這說明goto與標簽之間,不能出現變量。變量必須出現在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標簽之后,都是可以的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM