zoukankan      html  css  js  c++  java
  • 【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标签之后,都是可以的

  • 相关阅读:
    zipkin启动报错(Caused by: java.lang.ClassNotFoundException: zipkin.Component)的解决方法
    Java中的long与double的区别
    redis使用笔记
    解决node编程频繁修改代码,需要重启服务器问题
    远程连接mysql要点 虚拟主机定义与分类
    详析静态网站与动态网站区别(服务器ip dns 端口)
    JavaEE-实验四 HTML与JSP基础编程
    JavaEE-实验三 Java数据库高级编程
    JavaEE-实验二 Java集合框架实验
    mysql中文乱码 常见编码问题解决方法分享
  • 原文地址:https://www.cnblogs.com/lidabo/p/15557529.html
Copyright © 2011-2022 走看看