본문 바로가기
프로그래밍

[C++] switch case문 jump to case label 오류 문제 해결 방법

by _BlankSpace 2019. 1. 20.

switch case 문을 사용하다보면 아래와 같은 에러가 발생할 경우가 있다.


1
error: jump to case label [-fpermissive]
cs


처음에는 이것에 대해서 이해할 수가 없었는데, 찾아보니 굉장히 간단한 문법 오류였다.


사실, C/C++ 문법에서 switch case문은 굉장히 기초적인 문법 중에 하나라서,


이러한 오류가 발생할 지는 몰랐는데, 우연하게 위와 같은 오류를 확인할 수 있었다.


사실, 이때까지만 해도 미관상으로만 case 문에 블락 처리하는 것인줄 알았다..


1. 오류 확인


우선, 아래 코드를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
 
int main(void
{
    int num;
    std::cin >> num;
    switch (num)
    {   
        case 1 : 
            int i = 5;
            break;
 
        case 2 : 
            break;
 
        case 3 : 
        case 4 : 
            break;
 
        default :
            break;
    }   
    return 0;
}
cs


역시나 간단한 switch case 코드라고 할 수 있다.

그런데, 이 코드는 컴파일 에러를 유발시키는데, 9~11 줄을 보면, i 라는 변수를 생성하여 5로 초기화하였다.


컴파일 에러는 아래처럼 나온다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
switchCaseError1.cpp: In function ‘int main()’:
switchCaseError1.cpp:13:14: error: jump to case label [-fpermissive]
         case 2 :
              ^
switchCaseError1.cpp:10:17: note:   crosses initialization of ‘int i’
             int i = 5;
                 ^
switchCaseError1.cpp:16:14: error: jump to case label [-fpermissive]
         case 3 :
              ^
switchCaseError1.cpp:10:17: note:   crosses initialization of ‘int i’
             int i = 5;
                 ^
switchCaseError1.cpp:17:14: error: jump to case label [-fpermissive]
         case 4 :
              ^
switchCaseError1.cpp:10:17: note:   crosses initialization of ‘int i’
             int i = 5;
                 ^
switchCaseError1.cpp:20:9: error: jump to case label [-fpermissive]
         default :
         ^
switchCaseError1.cpp:10:17: note:   crosses initialization of ‘int i’
             int i = 5;
cs


jump to case label 이라는 에러가 발생하는 것을 볼 수 있다.

사실 이 포스팅의 결론은 이 에러를 어떻게 해결하냐는 것이다.


그것은 아래에서 확인하자.


2. 문제 해결 방법 

해결 방법은 굉장히 간단하다.

아래 코드를 확인해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
 
int main(void
{
    int num;
    std::cin >> num;
    switch (num)
    {   
        case 1 : {
            int i = 5;
            break;
        }
 
        case 2 : 
            break;
 
        case 3 : 
        case 4 : 
            break;
 
        default :
            break;
    }   
    return 0;
}
cs


이전 코드와는 별반 차이가 없는 것 같지만, 9~12라인을 보면 '{' 와 '}'로 감싸놓은 것을 볼 수 있을 것이다.

이처럼, case 문 안에서 변수를 생성하고 초기화를 할 경우에는 블락을 해야 한다.


3. 왜 블락을 이용해야 하는 것인가?

먼저, 확실하게 이게 답이라고는 할 수 없겠지만..

열심히 구글링해서 찾아본 결과, 다음의 이유라는 글을 찾았다.

https://en.cppreference.com/w/cpp/language/switch


제어 전달은 변수의 범위를 입력할 수 없으므로, 명령문 내에서 선언문이 나타나면 자체 선언문에서 범위를 지정해야 한다고 한다.

아래 코드를 보게 되면..


1
2
3
4
5
6
7
8
9
switch(1) {
    case 1int x = 0// 초기화
            std::cout << x << '\n';
            break;
    default// compilation error: jump to default:초기화 하지 않고 'x'범위 입력
             std::cout << "default\n";
             break;
}
cs


1
2
3
4
5
6
7
8
switch(1) {
    case 1: {  int x = 0;
               std::cout << x << '\n';
               break;
            } // 'x' 범위는 이 안에서만..
    defaultstd::cout << "default\n"// no error
             break;
}
cs


즉, case 1에서 선언한 x내용이 아래 case 에서도 있는 것으로 간주하는 것으로 생각하면 될 것 같다.

그래서 컴파일 에러를 보면, 각 case 마다 모두 에러가 발생하는 것을 볼 수 있다.


결국, case 문을 확실하게 구분하기 위해서도 블락으로 구분 짓는 것이 맞는 것 같다.


서로 이웃 추가는 항상 환영입니다.


'프로그래밍' 카테고리의 다른 글

[C++11] std::vector 배열 초기화 / C++98에서 대안 방법 정리  (0) 2019.01.20
[C++11] auto 정리  (0) 2017.05.24
[C++ 정복하자] 클래스의 기본  (0) 2017.05.20
[c++ 정복하자] 목차  (0) 2017.05.13
[STL] Vector 정리  (0) 2017.04.14

댓글