C에서 열거 형의 크기는 얼마입니까?


140

열거 형 값 집합을 만들고 있지만 각 열거 형 값의 너비는 64 비트 여야합니다. 내가 정확하게 기억한다면, 열거 형은 일반적으로 int와 크기가 같습니다. 그러나 컴파일러가 적어도 적어도 GCC에서 컴파일러가 값을 보유하는 데 필요한 너비를 열거 형으로 만들 수 있다고 생각했습니다. 그렇다면 64 비트 너비의 열거 형을 가질 수 있습니까?


1
따라서 내가 잘 이해한다면 2 ^ 32 열거 형으로는 충분하지 않습니까? 아니면 정렬 문제입니까, 왜 32가 아닌 64가되어야합니까? 나는 매우 궁금합니다.
jokoon

1
@ jokoon : 솔직히 더 이상 기억이 없습니다. 열거 형이 2 ^ 32-1보다 큰 값을 포함하기를 원한다고 생각합니다.
mipadi

열거 형과 포인터 사이의 통합이 필요한 경우 한 가지 용도가 있습니다.
데미

답변:


97

enum단지 유지에 충분한 보장되는 int값. 컴파일러는 정의 된 열거 상수를 기반으로 사용되는 실제 유형을 자유롭게 선택할 수 있으므로 사용자가 정의한 값을 나타낼 수있는 경우 더 작은 유형을 선택할 수 있습니다. 적합하지 않은 열거 상수 int가 필요한 경우 컴파일러 특정 확장을 사용해야합니다.


12
첫 번째 문장이 마지막 문장과 충돌하는 것 같습니다. 의 제한 enum이보다 크 int거나 작아야 한다는 제약이 있습니까? @MichaelStum의 답변에 이어 첫 번째 문장은 " 값 enum에 맞는 것만 보장 int됩니다"입니다.
HaskellElephant 2016 년

2의 보완 플랫폼에 대한 추악한 구현에 민감한 핵 (요즘 모든 시스템입니까?)이므로 음수 값을 포함하여 열거 형을 int만큼 크게 만들 수 있습니다. 그러나 권장되는 기술은 아닙니다.
persiflage

7
이 답변은 열거 형이 int. C99를 참조하는 Michael Stum의 답변 에 따르면 열거 형은 char.
Frank Kusters

3
이 답변의 첫 문장이 잘못되었습니다. 는 enum단지 열거에서 가장 큰 열거의 값을 보유 할 충분한 보장된다.
MM

91

현재 C 표준 (C99)에서 발췌 : http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2 열거 자 지정자
[...]
제약 조건
열거 상수의 값을 정의하는 식은 정수로 표현할 수있는 값을 갖는 정수 상수 식이어야합니다.
[...]
열거 된 각 유형은 char, 부호있는 정수 유형 또는 부호없는 정수 유형과 호환 가능해야합니다. 유형의 선택은 구현에 따라 정해지지 만 열거의 모든 멤버의 값을 나타낼 수 있어야합니다.

컴파일러가 표준을 따르는 데 능숙하지는 않지만 본질적으로 다음과 같습니다. 열거 형이 int 이외의 것을 보유하고 있다면 심오한 "지원되지 않는 동작으로 인해 1 ~ 2 년 안에 다시 물릴 수 있습니다".


3
그것만으로, 다음은 유효하다고 생각합니다. enum {LAST = INT_MAX, LAST1, LAST2}; 따라서 LAST2는 int로 표현할 수 없지만 그것을 정의하는 표현식은 없습니다.
Johannes Schaub-litb

4
실제 PDF에서 "열거 목록의 식별자는 int [...] 유형의 상수로 선언됩니다." 너무 장황하게 만들지 않기 위해 생략했습니다.
Michael Stum

2
참고 " 부호있는 정수 유형 또는 부호없는 정수 유형". 반드시 그런 것은 아닙니다 . 그리고 너무 종류의 정수이며, 어떤 구현 픽, 모든 값 맞게 ( "해야 된다 열거의 모든 구성원의 값을 나타내는 할 수"). intshortlong

3
주목할만한 : 열거 상수열거 된 유형 은 동일하지 않습니다 . 전자는 열거 선언 목록의 내용이고 후자는 실제 변수입니다. 따라서 열거 상수는이어야 int하지만 실제 열거 변수는 다른 유형일 수 있습니다. 이것은 표준에서 잘 알려진 불일치입니다.
Lundin

1
경우 : 룬딘의 입장을 명확히하기 위해 enum my_enum { my_value }, my_value유형이있을 것이다 int, 그러나 enum my_enum적어도 모든 열거 값을 나타내야 구현 정의 유형을 가질 수 있습니다. 따라서로 my_value변환이 좁아 질 수 enum my_enum있지만 오버플로가 발생하지는 않습니다.
P'Conbhui

17

이전 답변은 정확하지만 일부 컴파일러에는 표준을 위반하고 모든 값을 포함하는 가장 작은 유형을 사용하는 옵션이 있습니다.

GCC를 사용한 예 ( GCC 매뉴얼 문서 ) :

enum ord {
    FIRST = 1,
    SECOND,
    THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )

11
실제로, 내가 볼 수있는 한 이것은 표준을 위반하지 않습니다. Michael Stum의 답변에서 설명한 것처럼 표준을 사용하면 컴파일러에서 모든 값이 맞는 한 컴파일러에서 실제 유형의 열거 형을 선택할 수 있습니다.
sleske

2
나는 열거 형의 제한된 범위의 값을 활용하여 더 작은 유형으로 저장하는 MacOS C ++ 컴파일러로 작업했습니다. Metrowerks Codewarrior 또는 XCode인지 기억할 수 없습니다. 이것은 C ++ 표준 내에 있습니다. 일반적으로 sizeof (MyEnum) == sizeof (int)라고 가정 할 수 없습니다.
persiflage

0

열거 형의 마지막 값을 열거 형을 원하는 크기로 만들 수있을만큼 큰 값으로 설정하면 크기가 같아야합니다.

enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};

2
이 코드는 질문에 대답 할 수 있지만 문제를 해결하는 방법 및 / 또는 이유에 대한 추가 컨텍스트를 제공하면 답변의 장기적인 가치가 향상됩니다.
레오 팔

-1

enum변수 의 크기는 제어 할 수 없습니다 . 그것은 구현에 전적으로 달려 있으며, 컴파일러는를 사용하여 정수의 이름을 저장하는 옵션을 제공 enum하므로 정수 enum의 크기를 따릅니다.


-1

C 언어에서는 enum의 크기가 보장됩니다 int. 컴파일 시간 옵션 ( -fshort-enums)이 짧아집니다 (이 값이 64K 이하인 경우 주로 유용합니다). 크기를 64 비트로 늘리는 컴파일 시간 옵션이 없습니다.


-6

이 코드를 고려하십시오.

enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;

출력으로 4를 줄 것입니다. 따라서 enum포함 하는 요소의 수에 관계없이 크기는 항상 고정되어 있습니다.


6
Michael Stum의 답변이 맞습니다. 이것은 컴파일러마다 다릅니다. IAR EWARM으로 직접 시험해 볼 수 있습니다. IAR EWARM은 예제에 1을 표시합니다. 255 개 항목이 최대 인 경우는 2 층까지 256 항목을 추가 한 후 여전히 1. 표시
desowin

11
문제는 C ++에 관한 것이 아닙니다.
Michas

4
더 이상 C 또는 C ++를 작성하기 전에 알아야 할 중요한 사항 : 컴파일한다고해서 표준에 따라 합법적 인 것은 아닙니다. 주어진 결과를 얻는다고해서 표준이 항상 또는 다른 사용자가 코드를 실행할 때 항상 그렇게한다고 말합니다. 이와 같은 질문 에는 주어진 컴파일러 / ABI에 대한 표준 또는 적어도 구현 정의 사양을 참조하는 답변이 필요합니다 . 단순히 프로그램을 컴파일하고 실행하고 하루에 하나의 결과를 보는 것은 그러한 질문에 대한 교훈을 제공하지 않습니다.
underscore_d
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.