[c++] 작동해야하는 스위치에서 케이스를 건너 뛰기 위해 if (0)을 사용하고 있습니까?

C ++ switch 문에서 두 가지 경우가 모두 세 번째 경우로 넘어 가고 싶은 상황이 있습니다. 특히 두 번째 경우는 세 번째 경우로 넘어 가고 첫 번째 경우도 두 번째 경우 통과 하지 않고 세 번째 경우로 넘어갑니다 .

나는 멍청한 생각을 가지고 시도해 보았고 효과가있었습니다! 나는 두 번째의 경우 포장 if (0) {}. 다음과 같이 보입니다.

#ifdef __cplusplus
#  include <cstdio>
#else
#  include <stdio.h>
#endif

int main(void) {
    for (int i = 0; i < 3; i++) {
        printf("%d: ", i);
        switch (i) {
        case 0:
            putchar('a');
            // @fallthrough@
            if (0) {        // fall past all of case 1 (!)
        case 1:
            putchar('b');
            // @fallthrough@
            }
        case 2:
            putchar('c');
            break;
        }
        putchar('\n');
    }
    return 0;
}

실행하면 원하는 출력을 얻습니다.

0: ac
1: bc
2: c

나는 C와 C ++ (둘 다 clang과 함께)에서 시도해 보았고 같은 일을했습니다.

내 질문은 : 이것이 유효한 C / C ++입니까? 그것이하는 일을해야합니까?



답변

예, 이것은 허용되며 원하는 것을 수행합니다. A에 대한 switch문은 C ++ 표준은 말합니다 :

대 / 소문자 및 기본 레이블 자체는 제어 흐름을 변경하지 않으며 이러한 레이블에서 방해받지 않고 계속됩니다. 스위치에서 나가려면 break를 참조하십시오.

[참고 1 : 일반적으로 스위치의 주제 인 하위 문은 복합이고 case 및 기본 레이블은 (복합) 하위 문에 포함 된 최상위 문에 표시되지만 필수는 아닙니다. 선언문은 switch 문의 하위 문에 나타날 수 있습니다. — 끝 참고]

따라서 if명령문이 평가 될 때 if중간 케이스 레이블에 관계없이 명령문 의 규칙에 따라 제어 흐름이 진행됩니다 .


답변

네, 작동합니다. C의 switch 문에 대한 case 레이블은 goto 레이블과 거의 똑같습니다 (중첩 된 switch 문에서 작동하는 방법에 대한 몇 가지주의 사항이 있음). 특히, 그들은 “사례 내부”라고 생각하는 문장에 대한 블록을 스스로 정의하지 않으며, goto에서 할 수있는 것처럼 블록의 중간으로 점프하는 데 사용할 수 있습니다. 블록 중간으로 점프 할 때 변수 초기화 등의 점프와 관련하여 goto와 동일한주의 사항이 적용됩니다.

그렇게 말하면 실제로 다음과 같이 goto 문으로 작성하는 것이 더 분명합니다.

    switch (i) {
    case 0:
        putchar('a');
        goto case2;
    case 1:
        putchar('b');
        // @fallthrough@
    case2:
    case 2:
        putchar('c');
        break;
    }


답변

다른 답변에서 언급했듯이 이것은 표준에서 기술적으로 허용되지만 향후 코드 독자에게는 매우 혼란스럽고 명확하지 않습니다.

이것이 switch ... case문이 많은 인라인 코드가 아닌 함수 호출로 작성되어야하는 이유 입니다.

switch(i) {
case 0:
    do_zero_case(); do_general_stuff(); break;
case 1:
    do_one_case(); do_general_stuff(); break;
case 2:
    do_general_stuff(); break;
default:
    do_default_not_zero_not_one_not_general_stuff(); break;
}


답변