switch 문에 항상 기본 절이 포함되어야합니까?


254

첫 번째 코드 검토 중 하나에서 (뒤로) 모든 switch 문에 기본 절을 포함하는 것이 좋습니다. 나는 최근이 충고를 기억했지만 그 정당화가 무엇인지 기억하지 못한다. 지금 나에게는 꽤 이상하게 들린다.

  1. 항상 기본 진술을 포함시키는 합리적인 이유가 있습니까?

  2. 이 언어는 의존적입니까? 당시에 어떤 언어를 사용했는지 기억이 나지 않습니다.이 언어는 일부 언어에는 적용되고 다른 언어에는 적용되지 않을 수 있습니다.


9
언어에 따라 크게 달라질 것입니다
skaffman

답변:


276

스위치 케이스에는 거의 항상 케이스가 있어야합니다 default.

사용하는 이유 default

1. 예기치 않은 값을 '잡기'

switch(type)
{
    case 1:
        //something
    case 2:
        //something else
    default:
        // unknown type! based on the language,
        // there should probably be some error-handling
        // here, maybe an exception
}

2. 특별한 행동을위한 경우 인 '기본'행동을 다루기 위해.

메뉴 중심 프로그램과 bash 쉘 스크립트에서 이것을 많이 볼 수 있습니다. 또한 스위치 케이스 외부에서 변수가 선언되었지만 초기화되지 않은 경우에이를 확인할 수 있으며 각 경우마다 다른 것으로 초기화됩니다. 여기서 기본값은 변수에 액세스하는 라인 코드가 오류를 일으키지 않도록 초기화해야합니다.

3. 해당 사례를 다룬 코드를 읽는 사람에게 보여주기 위해.

variable = (variable == "value") ? 1 : 2;
switch(variable)
{
    case 1:
        // something
    case 2:
        // something else
    default:
        // will NOT execute because of the line preceding the switch.
}

이것은 지나치게 단순화 된 예이지만 요점은 코드를 읽는 사람이 왜 variable1 또는 2 이외의 것이 될 수 없는지 궁금 하지 않아야한다는 것입니다.


내가 사용하지 않음으로 생각할 수있는 유일한 경우 default입니다 스위치가 아니라 분명 다른 모든 대안을 행복하게 무시 될 수있는 무언가를 확인하는 경우

switch(keystroke)
{
    case 'w':
        // move up
    case 'a':
        // move left
    case 's':
        // move down
    case 'd':
        // move right
    // no default really required here
}

25
키 입력에 관한 예는 방금 말한 나머지 내용과 모순됩니다. : | 다음과 같은 약간의 설명이 의미가 있다고 생각합니다.이 경우에는 기본값을 신경 쓰지 않아도됩니다. 다른 키를 누르면 신경 쓰지 않아도되지만 변수가 전달되면 예상과 다릅니다. .
앤드류

1
동시에 GET 매개 변수를 확인하는 경우 사용자가 get url을 유효하지 않은 것으로 변경할 때마다 예외가 발생하지 않을 수 있습니다. [
Andrew

4
@Andrew WASD는 컴퓨터 게임 캐릭터 이동에 일반적으로 사용되며 다른 키를 다른 상호 작용에 할당 할 수 있으므로 기본 동작이 필요하지 않습니다. 이러한 종류의 스위치에서는 이동 기능을 호출하는 것이 좋습니다.
jemiloii

13
대소 문자가 누락되면 열거 형을 켤 때 일부 컴파일러에서 경고하고 기본 대소 문자를 추가하면 해당 경고가 표시되지 않습니다. 이것이 내 경험상 매우 일반적인 오류 원인이라는 것을 감안할 때 (열거 형 값이 추가 된 후 어딘가에 스위치를 업데이트하는 것을 잊어 버렸습니다), 이것은 기본 사례를 생략 해야하는 아주 좋은 이유 처럼 보입니다 .
rdb

3
@virusrocks 조건이 열거 형인 경우에도 예기치 않은 값을 가질 수 있습니다. 예를 들어 열거 형에 새 값을 추가하고 스위치를 업데이트하지 않은 경우 또한 일부 언어에서는 정수 값을 열거 형에 할당 할 수 있습니다. C ++ 에서 또는 같지 않은 enum MyEnum { FOO = 0, BAR = 1 }; MyEnum value = (MyEnum)2;유효한 MyEnum인스턴스를 만듭니다 . 이러한 문제 중 하나가 프로젝트에서 오류를 발생시키는 경우 기본 사례는 종종 디버거가 필요하지 않은 오류를 매우 빨리 찾을 수 있도록 도와줍니다! FOOBAR
cdgraham

54

아니.

기본 조치가 없으면 상황이 중요합니다. 몇 가지 가치에 대해서만 행동한다면?

게임에서 키 누르기를 읽는 예를 들어보십시오.

switch(a)
{
   case 'w':
     // Move Up
     break;
   case 's':
     // Move Down
     break;
   case 'a':
     // Move Left
     break;
   case 'd':
     // Move Right
     break;
}

첨가:

default: // Do nothing

시간 낭비 일 뿐이며 이유없이 코드의 복잡성을 증가시킵니다.


14
좋은 예입니다. 그러나 실제로 간단한 // do nothing주석 으로 기본 절을 추가 하면 이것이 'OK'가 아닌 다른 스위치 명령문과 달리 모든 경우에 적용되지 않는 경우 'OK'임을 분명히 알 수 있습니다.
네일

8
아니요. 코딩은 일부 경우를 다루는 것이 아닙니다. 또한 문서 역할을합니다. default :를 작성하고 // 아무것도하거나 다른 것을하지 않으면 코드의 가독성이 좋아집니다.
박종암

22
다른 의견에 동의하지 않습니다. 기본값 추가 // 코드 작동 방식을 모르는 경우 아무 것도 추가하지 않습니다. 기본값없이 switch 문을 볼 수 있으며 기본값은 아무것도하지 않는 것임을 알 수 있습니다. 어수선 함을 추가한다고해서 이것이 더 명확 해지지는 않습니다.
Robert Noack

바로 그거죠. 그것은 포스트 포스트 매개 변수를 전달하는 것과 같은 개념입니다. 당신은 당신이 아닌 다른 사람들을 돌보는 사람들을 처리합니다.
Jimmy Kane

2
@jybrd 만약 당신이 이전 개발자가 의도적으로 기본값을 생략했다는 것을 믿지 않는다면 왜 그것들을 넣는 것이 옳았다 고 믿을 것입니까? 기본값은 완전히 빠진 것처럼 실수로 비어있을 수 있습니다. 사소한 것에 대해서는 언급이 필요하지 않습니다. 이것은 코드 혼란입니다. 대신 의도를 보여주기 위해 전체 적용 단위 테스트를 작성하십시오. (그냥 내 의견)
Robert Noack

45

기본 상황이없는 것은 실제로 어떤 상황에서는 유리할 수 있습니다.

스위치 케이스가 열거 형 값인 경우 기본 케이스를 사용하지 않으면 케이스가없는 경우 컴파일러 경고가 표시 될 수 있습니다. 이렇게하면 나중에 새로운 열거 형 값이 추가되고 스위치에서 이러한 값에 대한 사례를 추가하는 것을 잊어 버린 경우 컴파일 타임에 문제에 대해 알 수 있습니다. 유효하지 않은 값이 열거 형 유형으로 캐스팅 된 경우 코드에서 처리되지 않은 값에 대해 적절한 조치를 취해야합니다. 따라서 이것은 간단한 경우에 가장 잘 작동 할 수 있습니다.

enum SomeEnum
{
    ENUM_1,
    ENUM_2,
    // More ENUM values may be added in future
};

int foo(SomeEnum value)
{
    switch (value)
    {
    case ENUM_1:
        return 1;
    case ENUM_2:
        return 2;
    }
    // handle invalid values here
    return 0;
 }

이것은 중요한 관찰입니다! int를 열거 형으로 캐스팅 할 수 없기 때문에 Java에서 훨씬 더 많이 적용됩니다.
Lii

2
귀하의 예제에서 switch-statement 이후에 리턴하는 대신 예외를 던질 수 있습니다. 이런 식으로 컴파일러에 의한 정적 검사와 예기치 않은 일이 발생하면 명확한 오류가 발생할 수 있습니다.
Lii

1
나는 동의한다. 예를 들어 Swift에서 switch는 철저해야합니다. 그렇지 않으면 컴파일러 오류가 발생합니다! 기본값을 제공하면이 유용한 오류가 사라집니다. 반면, 모든 경우를 처리하는 경우 기본값을 제공하면 실제로 컴파일러 경고 (연결할 수없는 명령문)가 발생합니다.
Andy

1
방금 기본값이 없으면 컴파일러에서 경고가 발생하는 버그를 수정했습니다. 따라서 일반적으로 열거 형 변수 전환에는 기본값이 없어야합니다.
notan

42

어떤 언어로 작업하든 항상 기본 절을 사용합니다.

일이 잘못 될 수 있습니다. 가치는 당신이 기대하는 것과 같지 않을 것입니다.

기본 절을 포함하지 않으려면 가능한 값 세트를 알고 있다고 확신합니다. 가능한 값 세트를 알고 있다고 생각되면 값이이 가능한 값 세트를 벗어나는 경우이를 알려고합니다. 확실히 오류입니다.

이것이 항상 기본 절을 사용하고 예를 들어 Java에서 오류를 발생시키는 이유입니다.

switch (myVar) {
   case 1: ......; break;
   case 2: ......; break;
   default: throw new RuntimeException("unreachable");
}

"연결할 수없는"문자열보다 더 많은 정보를 포함시킬 이유가 없습니다. 실제로 발생하는 경우 어쨌든 소스 및 변수 값 등을 확인해야하며 예외 스택 추적에는 해당 행 번호가 포함되므로 예외 메시지에 더 많은 텍스트를 쓰는 데 시간을 낭비 할 필요가 없습니다.


39
throw new RuntimeException("myVar invalid " + myVar);디버거를 사용하지 않고 변수를 검사하지 않고도 버그를 파악하고 수정하기에 충분한 정보를 제공 할 수 있기 때문에 선호합니다 .
Chris Dodd

1
값이 사례 중 하나와 일치하지 않는 오류 조건이 아닌 경우 어떻게합니까?
Gabe

4
오류 조건이 아닌 경우을 필요로하지 않습니다 default:. 그러나 더 자주는 그렇지 않습니다 myVar. 열거 된 것 이외의 다른 값을 가질 수 없다고 생각하기 때문에 기본값을 생략합니다 . 그러나 변수가 "가능한"값 이외의 값을 가질 때 실제 생활에서 놀랐던 횟수를 셀 수 없습니다. 이 경우 나중에 다른 오류 (디버깅하기가 더 어렵다) 또는 잘못된 답변 (테스트에서 간과 될 수 있음)을 일으키는 것이 아니라 예외를 즉시 확인하게 된 예외에 대해 감사했습니다.
Adrian Smith

2
나는 Adrian에 동의합니다. 열심히 실패하고 일찍 실패하십시오.
Slappy

이 상황은 처리 된 값 중 하나 인 어설 션과 매우 유사하므로 AssertionError대신 대신을 사용 하는 것이 좋습니다 . 또한 누군가가 오류를 잡고 삼킬 가능성은 적습니다. RuntimeExceptionmyVar
Philipp Wendler

15

우리 회사에서는 Avionics and Defense 시장을위한 소프트웨어를 작성하며 스위치 문에있는 모든 경우를 명시 적으로 처리해야하기 때문에 항상 기본 진술을 포함합니다 ( '아무것도하지 않음'이라는 주석 일지라도). 예상치 못한 (또는 불가능하다고 생각하는) 값에서 오작동하거나 단순히 충돌 할 수는 없습니다.

기본 사례가 항상 필요한 것은 아니지만 항상 요구하면 코드 분석기로 쉽게 확인할 수 있습니다.


1
나는 일할 때와 같은 요구 사항이 있습니다. 엄격한 안전 점검을 통과해야하고 종종 EMI에 노출되는 임베디드 µController 용 코드를 작성합니다. 열거 된 변수가 열거 목록에없는 값을 가지지 않는다고 가정하는 것은 무책임합니다.
oosterwal

12

"switch"문에 항상 기본 절이 포함 되어야합니까 ? 아니요 . 일반적으로 기본값을 포함 해야합니다 .

기본 절을 포함하면 오류 조건을 주장하거나 기본 동작을 제공하는 등의 조치가 필요한 경우에만 의미가 있습니다. 하나의 "그냥 이유"를 포함하는 것은화물 컬트 프로그래밍이며 가치를 제공하지 않습니다. 모든 "if"문에 "else"가 포함되어야한다고 말하는 것과 같은 "스위치"입니다.

이해가되지 않는 간단한 예는 다음과 같습니다.

void PrintSign(int i)
{
    switch (Math.Sign(i))
    {
    case 1:
        Console.Write("positive ");
        break;
    case -1:
        Console.Write("negative ");
        break;
    default: // useless
    }
    Console.Write("integer");
}

이것은 다음과 같습니다.

void PrintSign(int i)
{
    int sgn = Math.Sign(i);
    if (sgn == 1)
        Console.Write("positive ");
    else if (sgn == -1)
        Console.Write("negative ");
    else // also useless
    {
    }
    Console.Write("integer");
}

동의하지 않습니다. IMHO, 기본값이 존재하지 않아야 할 유일한 시간은 현재와 현재까지 입력 집합이 변경 될 수있는 방법이없고 가능한 모든 값을 가지고있는 경우입니다. 내가 생각할 수있는 가장 간단한 경우는 데이터베이스의 부울 값입니다 (SQL 변경 때까지) 유일한 대답은 true, false 및 NULL입니다. 다른 경우에는 "Should n't Happen!"이라는 단정 또는 예외가있는 기본값이 있습니다. 말이 되네요 코드가 변경되고 하나 이상의 새로운 값이있는 경우이를 코딩 할 수 있으며 그렇지 않은 경우 테스트가 중단됩니다.
Harper Shelby

4
@Harper : 귀하의 예는 "오류 상태 확인"범주에 속합니다.
Gabe

나는 나의 예가 표준이며, 가능한 모든 경우가 100 % 보장 될 수 있고 디폴트가 필요하지 않은 소수의 경우는 예외라고 주장한다. 당신의 대답은 할 일이 없어 질 때보 다 더 자주 발생하지 않는 것처럼 들리는 방식으로 (적어도 나에게는) 말로 표현됩니다.
Harper Shelby

@Harper : 좋아, 나는 아무것도하지 않는 상황이 덜 일반적임을 나타 내기 위해 문구를 변경했습니다.
Gabe

4
나는 default:그러한 경우에 당신의 가정을 성문화 한다고 생각합니다 . 예를 들어, sgn==0인쇄 할 때 integer(긍정적이든 부정적이든) 괜찮 습니까, 아니면 오류입니까? 그 코드를 읽으면 말하기가 어렵습니다. zero이 경우 not not 을 작성 integer하고 프로그래머 sgn가 -1 또는 +1 일 수 있다고 가정했다고 가정합니다 . 이 경우 default:프로그래머가 가정 오류를 조기에 포착하여 코드를 변경할 수 있습니다.
Adrian Smith

7

내가 보는 한 대답은 'default'는 선택 사항입니다. 스위치는 항상 기본값을 포함해야한다는 것은 모든 'if-elseif'는 'else'를 포함해야한다고 말하는 것과 같습니다. 기본적으로 수행 할 논리가 있으면 'default'문이 있어야하지만 그렇지 않으면 코드가 아무 것도 수행하지 않고 계속 실행될 수 있습니다.


6

실제로 필요 하지 않을 때 기본 절을 갖는 것은 방어 프로그래밍입니다. 이것은 일반적으로 너무 많은 오류 처리 코드로 인해 지나치게 복잡한 코드로 이어집니다. 이 오류 처리 및 탐지 코드는 코드의 가독성을 떨어 뜨리고 유지 관리를 어렵게하며 결국 해결하는 것보다 더 많은 버그를 유발합니다.

따라서 기본값에 도달하지 않으면 추가 할 필요가 없다고 생각합니다.

"도달하지 말아야한다"는 소프트웨어의 버그에 도달하면 사용자 입력 등으로 인해 원치 않는 값이 포함 된 값을 테스트해야 함을 의미합니다.


3
예기치 않은 경우가 발생하는 또 다른 일반적인 이유 : 코드의 다른 부분은 아마도 몇 년 후에 수정됩니다.
Hendrik Brummermann

실제로 이것은 매우 비열한 행동입니다. 적어도 assert () 절을 추가하겠습니다. 그러면 버그가있을 때마다 쉽게 감지됩니다.
커트 패틴

5

언어에 따라 다르지만 C에서 열거 형 유형을 전환하고 가능한 모든 값을 처리하면 기본 사례를 포함하지 않는 것이 좋습니다. 이렇게하면 나중에 추가 열거 형 태그를 추가하고 스위치에 추가하는 것을 잊어 버린 경우 유능한 컴파일러가 누락 된 사례에 대한 경고를 표시합니다.


5
"가능한 모든 값"은 열거 형으로 처리되지 않을 것입니다. 특정 값이 명시 적으로 정의되지 않은 경우에도 열거 형으로 정수를 캐스트 할 수 있습니다. 그리고 어떤 컴파일러가 누락 된 경우에 대해 경고합니까?
TrueWill

1
@TrueWill : 그렇습니다. 명백한 캐스트를 사용하여 이해하기 어려운 난독 화 된 코드를 작성할 수 있습니다. 이해할 수있는 코드를 작성하려면이를 피해야합니다. gcc -Wall(유능한 컴파일러의 가장 일반적인 공통 분모) 정렬 스위치에서 처리되지 않은 열거 형에 대한 경고를 제공합니다.
Chris Dodd

4

switch 문에 엄격하게 정의 된 레이블 또는 값 집합 만 있다는 것을 알고 있다면이 방법을 사용하여 항상 유효한 결과를 얻을 수 있습니다. 프로그래밍 방식으로 / 논리적으로 표시되는 레이블 위에 기본값을 추가하십시오. 다른 값을 처리하는 데 가장 적합합니다.

switch(ResponseValue)
{
    default:
    case No:
        return false;
    case Yes;
        return true;
}

여기에 콜론이 default계속 필요한가요? 아니면 이렇게하면 생략 할 수있는 특수 구문이 허용됩니까?
Ponkadoodle

콜론이 필요합니다. 오타였습니다.주의를 기울여 주셔서 감사합니다.
deegee

3

Atleast는 Java에서 필수는 아닙니다. JLS에 따르면, 최소한 하나의 기본 사례가 존재할 수 있다고한다. 이는 기본 사례가 허용되지 않음을 의미합니다. 때로는 switch 문을 사용하는 컨텍스트에 따라 다릅니다. 예를 들어 Java에서 다음 스위치 블록에는 기본 대 / 소문자가 필요하지 않습니다.

private static void switch1(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        break;
    case "Tuesday":
        System.out.println("Tuesday");
        break;
    }
}

그러나 문자열을 반환 할 것으로 예상되는 다음 방법에서는 컴파일 오류를 피하기 위해 기본 사례가 편리합니다.

    private static String switch2(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        return name;

    case "Tuesday":
        System.out.println("Tuesday");
        return name;

    default:
        return name;
    }
}

마지막에 return 문을 사용하여 기본 대소 문자를 지정하지 않고 위의 메소드에 대한 컴파일 오류를 피할 수 있지만 기본 대소 문자를 제공하면 더 읽기 쉽습니다.


3

MISRA C 와 같은 일부 (오래된) 지침에 따르면 다음과 같습니다.

최종 기본 조항의 요구 사항은 방어 프로그래밍입니다. 이 조항은 적절한 조치를 취하거나 조치를 취하지 않은 이유에 대한 적절한 의견을 포함해야합니다.

이 조언은 현재 관련된 기준에 기반하지 않기 때문에 구식입니다. 할란 카 슬러가 말한 눈부신 누락은 다음과 같습니다.

기본 사례를 제외하면 처리되지 않은 사례가 표시 될 때 컴파일러가 선택적으로 경고하거나 실패 할 수 있습니다. 정적 검증은 결국 동적 검사보다 우수하므로 동적 검사가 필요할 때 가치있는 희생이 아닙니다.

Harlan도 시연 한 것처럼 기본 사례와 동등한 기능을 스위치 후에 다시 만들 수 있습니다. 각 사례가 조기에 반환 될 때 사소한 것입니다.

동적 검사의 일반적인 요구는 넓은 의미에서 입력 처리입니다. 값이 프로그램의 제어 범위를 벗어나면 신뢰할 수 없습니다.

이것은 또한 Misra가 극단적 인 방어 프로그래밍 의 관점 을 취하는 곳입니다 . 유효하지 않은 값이 물리적으로 표현 가능한 한, 프로그램의 정확성에 관계없이 확인해야합니다. 하드웨어 오류가있을 때 소프트웨어를 최대한 신뢰할 수 있어야한다면 이치에 맞습니다. 그러나 Ophir Yoktan이 말했듯이 대부분의 소프트웨어는 버그를 다루지 않는 것이 좋습니다. 후자의 관행은 때때로 공격적인 프로그래밍 이라고 불린다 .


2

예기치 않은 값이 들어 오려면 기본값이 있어야합니다.

그러나 Adrian Smith는 기본 오류 메시지가 완전히 의미가 없다는 것에 동의하지 않습니다. 사용자가 보지 못할 것으로 보지 않은 처리되지 않은 사례가있을 수 있으며 (도달 할 수 없음) "도달 할 수 없음"과 같은 메시지는 전적으로 의미가 없으며 해당 상황에있는 사람을 도울 수 없습니다.

예를 들어, 완전히 의미없는 BSOD를 몇 번이나 경험 했습니까? 아니면 0x352FBB3C32342에서 치명적인 예외가 있습니까?


예를 들어-항상 오류 메시지를 보는 것은 개발자 만이 아니라는 점을 기억하십시오. 우리는 현실 세계에 살고 사람들은 실수를합니다.
John Hunt

2

스위치 값 ( switch (variable ))이 기본 사례에 도달 할 수없는 경우 기본 사례가 전혀 필요하지 않습니다. 기본 사례를 유지하더라도 전혀 실행되지 않습니다. 데드 코드입니다.


2

선택적 코딩 '컨벤션'입니다. 사용 여부에 따라 필요한지 여부가 결정됩니다. 나는 개인적으로 당신이 필요하지 않으면 거기에 있으면 안된다고 믿습니다. 사용자가 사용하거나 접근하지 않는 것을 왜 포함시켜야합니까?

대소 문자 가능성이 제한되면 (즉, 부울) 기본 절은 중복입니다 !


2

switch명령문에 기본 사례 가없는 경우 개발 단계에서 예측할 수없는 특정 시점에 해당 사례가 발생하면 동작을 예측할 수 없습니다. 사례를 포함하는 것이 좋습니다 default.

switch ( x ){
  case 0 : { - - - -}
  case 1 : { - - - -}
}

/* What happens if case 2 arises and there is a pointer
* initialization to be made in the cases . In such a case ,
* we can end up with a NULL dereference */

이러한 관행은 NULL 역 참조 , 메모리 누수 및 기타 유형의 심각한 버그 와 같은 버그를 초래할 수 있습니다 .

예를 들어 각 조건이 포인터를 초기화한다고 가정합니다. 그러나 default경우가 발생 하고이 경우 초기화하지 않으면 null 포인터 예외가 발생할 가능성이 있습니다. 따라서 default사소한 경우에도 case 문 을 사용하는 것이 좋습니다 .


2

enum에서 사용하는 스위치에는 기본 경우가 필요하지 않을 수 있습니다. switch에 모든 값이 포함 된 경우 기본 사례는 절대 실행되지 않습니다. 따라서이 경우에는 필요하지 않습니다.


1

특정 언어의 스위치 작동 방식에 따라 다르지만 대소 문자가 일치하지 않는 대부분의 언어에서는 경고없이 switch 문을 통해 실행됩니다. 일부 값 집합을 예상하고 스위치에서 처리했다고 가정하지만 입력에서 다른 값을 얻습니다. 아무 일도 일어나지 않으며 아무 일도 일어나지 않았다. 기본적으로 사례를 발견 한 경우 문제가 있음을 알 수 있습니다.


1

위의 Vanwaril에 대한 가장 투표가 많은 답변에 동의하지 않습니다.

모든 코드는 복잡성을 추가합니다. 또한 테스트 및 문서화를 수행해야합니다. 적은 코드를 사용하여 프로그래밍 할 수 있으면 항상 좋습니다. 내 의견은 비 완전 스위치 문에 기본 절을 사용하고 철저한 스위치 문에 기본 절을 사용하지 않는다는 것입니다. 내가 올바르게했는지 확인하기 위해 정적 코드 분석 도구를 사용합니다. 자세한 내용을 살펴 보겠습니다.

  1. 비 완료 스위치 설명 : 항상 기본값이 있어야 합니다. 이름에서 알 수 있듯이 가능한 모든 값을 다루지 않는 진술입니다. 예를 들어 정수 값 또는 문자열에 대한 switch 문도 불가능할 수 있습니다. 여기서 Vanwaril의 예를 사용하고 싶습니다 (그가이 예를 사용하여 잘못된 제안을했다고 생각합니다. 여기에서 반대를 진술하기 위해 사용합니다-> 기본 문장 사용).

    switch(keystroke)
    {
      case 'w':
        // move up
      case 'a':
        // move left
      case 's':
        // move down
      case 'd':
        // move right
      default:          
        // cover all other values of the non-exhaustive switch statement
    }
    

    플레이어는 다른 키를 누를 수 있습니다. 그런 다음 아무것도 할 수 없었습니다 (기본 사례에 주석을 추가하여 코드에 표시 할 수 있음). 예를 들어 화면에 무언가를 인쇄해야합니다. 이 사례는 발생할 수있는 것과 관련이 있습니다.

  2. 철저한 스위치 설명 : 이러한 스위치 설명은 가능한 모든 값 (예 : 등급 시스템 유형의 열거에 대한 스위치 설명)을 포괄합니다. 코드를 처음 개발할 때는 모든 값을 쉽게 다룰 수 있습니다. 그러나 우리는 인간이기 때문에 일부를 잊을 수있는 작은 기회가 있습니다. 또한 나중에 열거 형 값을 추가하여 모든 스위치 문을 다시 철저하게 수정해야하면 오류 지옥에 대한 경로가 열립니다. 간단한 솔루션은 정적 코드 분석 도구입니다. 이 도구는 모든 스위치 명령문을 점검하고 완전한지 또는 기본값이 있는지 확인해야합니다. 다음은 완전한 스위치 설명의 예입니다. 먼저 열거 형이 필요합니다.

    public enum GradeSystemType {System1To6, SystemAToD, System0To100}
    

    그런 다음이 열거 형의 변수가 필요합니다 GradeSystemType type = .... 철저한 switch 문은 다음과 같습니다.

    switch(type)
    {
      case GradeSystemType.System1To6:
        // do something
      case GradeSystemType.SystemAToD:
        // do something
      case GradeSystemType.System0To100:
        // do something
    }
    

    따라서 GradeSystemType예를 들어 System1To3정적 코드 분석 도구 를 확장하면 기본 절이없고 switch 문이 완전하지 않다는 것을 감지해야하므로 저장됩니다.

하나만 추가하면됩니다. 우리가 항상 default절을 사용 하면 정적 코드 분석 도구는 항상 default절을 감지하므로 전체 또는 비 완전 스위치 문을 감지하지 못할 수 있습니다. 열거 형을 다른 값으로 확장하고 하나의 switch 문에 추가하는 것을 잊어 버린다면 알 수 없으므로 매우 나쁩니다.


0

switch 문은 항상 기본 절을 포함해야합니까? 기본 경우를 제외하고 스위치 케이스가 존재할 수 없습니다. 스위치 케이스의 경우 기본 케이스는 switch(x)다른 케이스 값과 일치하지 않는 경우이 스위치 스위치 값 을 트리거 합니다.


0

나는 이것이 언어마다 다르며 C ++ 경우 열거 형 클래스 유형에 대한 사소한 점이라고 생각 합니다. 전통적인 C 열거보다 더 안전한 것으로 보입니다. 그러나

std :: byte 구현을 보면 다음과 같습니다.

enum class byte : unsigned char {} ;

출처 : https://en.cppreference.com/w/cpp/language/enum

또한 이것을 고려하십시오 :

그렇지 않으면 T가 고정 기본 유형으로 범위가 지정되거나 범위가 지정되지 않은 열거 유형이고, braced-init-list에 하나의 이니셜 라이저가 있고 이니셜 라이저에서 기본 유형으로의 변환이 좁지 않은 경우 및 초기화는 직접 목록 초기화이며 초기화는 초기화자를 기본 유형으로 변환 한 결과로 초기화됩니다.

(C ++ 17부터)

출처 : https://en.cppreference.com/w/cpp/language/list_initialization

열거자가 정의되지 않은 값을 나타내는 열거 클래스의 예입니다. 이러한 이유로 열거 형을 완전히 신뢰할 수 없습니다. 응용 프로그램에 따라 중요 할 수 있습니다.

그러나 @Harlan Kassler가 자신의 게시물에서 말한 것을 정말 좋아하며 어떤 상황에서는 그 전략을 사용하기 시작할 것입니다.

안전하지 않은 열거 클래스의 예 :

enum class Numbers : unsigned
{
    One = 1u,
    Two = 2u
};

int main()
{
    Numbers zero{ 0u };
    return 0;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.