source

열거형이 목록에 없는 값을 가질 수 있습니까?

ittop 2023. 7. 16. 17:54
반응형

열거형이 목록에 없는 값을 가질 수 있습니까?

이봐, 우리는.

enum E
{
  Foo = 0,
  Bar = 1
};

이제, 우리는.

enum E v = ( enum E ) 2;

그리고 나서.

switch ( v )
{
  case Foo:
    doFoo();
  break;
  case Bar:
    doBar();
  break;
  default:
    // Is the compiler required to honor this?
    doOther();
  break;
}

열 된 가 모 처 로 컴 므 러 가 일 최 화 적 하 파 여 하 리 값 을 한 능 든 거 ▁the ▁away , ▁since 하 화 ▁it 여 ▁handles ▁fordefault위의 분기 또는 열거값이 목록에 없는 경우 지정되지 않거나 정의되지 않은 동작이 있습니까?

C와 C++의 동작이 비슷할 것으로 예상하기 때문에 두 언어에 대한 질문입니다.하지만 그 경우에 C와 C++의 차이가 있다면 그것에 대해서도 알아두면 좋을 것 같습니다.

C++ 상황

C++에서 각 열거형에는 기본 적분 유형이 있습니다.명시적으로 지정된 경우(예:enum test2 : long { a,b};) 또는 해당하는 경우int범위가 지정된 열거형(예:enum class test { a,b };):

[dcl.enum]/5: 각 열거형은 다른 모든 유형과 다른 유형을 정의합니다.각 열거형에는 기본 유형도 있습니다. (...) 명시적으로 지정하지 않으면 범위 열거형의 기본 유형은 int입니다.이러한 경우에는 기본 유형이 고정되어 있다고 합니다.

기본 형식이 명시적으로 고정되지 않은 범위가 지정되지 않은 열거형의 경우(), 표준은 컴파일러에 더 많은 유연성을 제공합니다.

[dcl.enum]/7: 기본 형식이 고정되지 않은 열거형의 경우, 기본 형식은 열거형에 정의된 모든 열거자 값을 나타낼 수 있는 통합 형식입니다. (...) 열거자의 값이 int 또는 unsigned int에 들어가지 않는 한 기본 유형이 int보다 클 수 없다는 것을 제외하고 기본 유형으로 사용되는 통합 유형은 구현 정의됩니다.

매우 까다로운 문제입니다. 열거형 변수로 유지할 수 있는 값은 기본 유형이 고정되어 있는지 여부에 따라 달라집니다.

  • 이 값이 고정된 경우, " 열거형의 값은 기본 형식의 입니다."

  • 또는 가장 작은 열거자와 가장 큰 열거자를 수용할 수 있는 가장 작은 비트 필드의 최소값과 최대값 내의 적분 값입니다.

두 번째 경우입니다. 코드가 대부분의 컴파일러에서 작동하지만 가장 작은 비트 필드의 크기는 1이므로 호환되는 모든 C++ 컴파일러에서 유지할 수 있는 값은 0과 1 사이의 값뿐입니다.

결론:값을 2로 설정하려면 열거형을 범위가 지정된 열거형으로 만들거나 기본 유형을 명시적으로 지정해야 합니다.**

자세한 내용:

C 상황

C 상황은 훨씬 간단합니다(C11).

6.2.5/16: 열거형은 명명된 정수 상수 값 집합으로 구성됩니다.각각의 고유 열거형은 서로 다른 열거형을 구성합니다.

그래서 기본적으로 이것은 int입니다.

6.7.2.2./2 열거 상수의 값을 정의하는 표현식은 int로 표현할 수 있는 값을 갖는 정수 상수 표현식이어야 합니다.

다음과 같은 제한이 있습니다.

열거된 각 유형은 char, 부호 있는 정수 유형 또는 부호 없는 정수 유형과 호환되어야 합니다.유형의 선택은 구현 정의되지만 열거형의 모든 구성원의 값을 나타낼 수 있어야 합니다.

enumtype은 모든 것을 담을 수 있을 만큼 충분히 큰 정수형입니다.enum상수:

(C11, 6.7.2.2p4) "각 열거형은 char, 부호 있는 정수형 또는 부호 없는 정수형과 호환되어야 합니다.형식의 선택은 구현 정의, 110)이지만 열거형의 모든 구성원의 값을 나타낼 수 있어야 합니다."

다음에 대해 선택된 유형을 예로 들어 보겠습니다.enum E이라_Bool.a._Bool는 " 만" 값만 할 수 .0그리고.1그것을 가질 수 없습니다._Bool 저을는개체와 다른 하는 객체0또는1정의되지 않은 동작을 호출하지 않습니다.

의 할 수 .enum E형식만 유지할 수 있습니다.0또는1엄격하게 준수하는 프로그램에서, 그리고 그렇게 해서 최적화될 수 있습니다.default스위치 케이스

C++표준 7.2.7 [dcl.enum]:

열거자에 의해 정의되지 않은 값을 가진 열거형을 정의할 수 있습니다.

따라서 열거자 목록에 나열되지 않은 열거 값을 가질 수 있습니다.

그러나 특정한 경우 '기본 유형'은 '고정'이 아닙니다(7.2.5).이 경우 사양에는 어떤 것이 기본 유형인지는 명시되어 있지 않지만, 반드시 통합되어야 합니다.char가 이러한 유형 중 가장 작기 때문에 열거자 목록에 지정되지 않은 열거형의 다른 값이 있다는 결론을 내릴 수 있습니다.

그나저나, 컴파일러는 v에 할당된 다른 값이 없다고 판단할 수 있을 때 당신의 사례를 최적화할 수 있다고 생각합니다. 이는 안전하지만, 그렇게 똑똑한 컴파일러는 아직 없다고 생각합니다.

또한 7.2/10:

산술 또는 열거형 형식의 식을 열거형 형식으로 명시적으로 변환할 수 있습니다.값이 열거형 유형의 열거형 값 범위에 있으면 값이 변경되지 않습니다. 그렇지 않으면 결과 열거형 값이 지정되지 않습니다.

InC 열거자에 유형이 있음int따라서 모든 정수 값을 열거형 유형의 개체에 할당할 수 있습니다.

C 표준에서(6.7.2.2 열거형 지정자)

3 열거자 목록의 식별자는 int 형식을 가진 상수로 선언되며, 그러한 상수가 허용되는 곳이면 어디에서나 나타날 수 있습니다.

InC++ 열거자에는 이를 정의하는 열거형이 있습니다.C++에서는 언더레이 유형을 명시적으로 지정하거나 컴파일러가 자체적으로 허용되는 최대값을 계산해야 합니다.

C++ 표준에서 (7.2 열거 선언)

5 각 열거형은 다른 모든 유형과 다른 유형을 정의합니다.각 열거형에는 기본 유형도 있습니다.기본 형식은 enum-base를 사용하여 명시적으로 지정할 수 있습니다. 명시적으로 지정하지 않으면 범위 열거 형식의 기본 형식은 int입니다.이러한 경우에는 기본 유형이 고정되어 있다고 합니다.열거형 지정자의 닫는 대괄호 뒤에 각 열거형에는 열거형 유형이 있습니다.

따라서 C에서 열거형의 가능한 값은 임의의 정수 값입니다.컴파일러가 기본 레이블을 제거하는 스위치를 최적화하지 못할 수 있습니다.

C와 C++에서는 이것이 작동할 수 있습니다.

둘 다 동일한 코드:

#include <stdio.h>

enum E
{
  Foo = 0,
  Bar = 1
};

int main()
{
    enum E v = (enum E)2;    // the cast is required for C++, but not for C
    printf("v = %d\n", v);
    switch (v) {
    case Foo:
        printf("got foo\n");
        break;
    case Bar:
        printf("got bar\n");
        break;
    default:
        printf("got \n", v);
        break;
    }
}

두 가지에 대해 동일한 출력:

v = 2
got default

C서에는,enum는 적분 유형이므로 주조하지 않고 정수 값을 할당할 수 있습니다.에서, C++는enum고유한 유형입니다.

언급URL : https://stackoverflow.com/questions/33812998/is-it-allowed-for-an-enum-to-have-an-unlisted-value

반응형