Programing

두 개의 다른 열거형-정수 값이 동일한 이유는 무엇인가?

c10106 2022. 5. 20. 21:28
반응형

두 개의 다른 열거형-정수 값이 동일한 이유는 무엇인가?

내가 이렇게 열거형 평일을 정의한다면:

enum weekday {
    MON,
    TUE,
    WED,
    THU,
    FRI,
};

그러면 기본적으로 MON은 내부적으로 0, TUE는 1, WED는 2...

하지만 내가 이것을 이렇게 정의한다면:

enum weekday {
    MON,
    TUE = 0,
    WED,
    THU,
    FRI,
};

그럼 둘 다MON그리고TUE0이라는 값을 얻을 수 있을 것이다.

시스템이 내부적으로 MON과 TUE를 어떻게 구별할 것인가?내 말은, 만약 내가 이런걸 선언한다면:

enum weekday today = 0;

그럼 오늘인가?MON또는TUE아니면, 철학적으로 말하면, 둘 다?

C 열거형은 "진짜" 정수로, 우연히 그렇게 구현되었기 때문만이 아니라, 표준이 열거형을 정수 값으로 정의하기 때문이다.그래서 그 가치는today"진짜" 0. 0이라는 값에 대해 두 개의 다른 이름을 만든 것뿐입니다.

그렇다면 "오늘은 MON인가 TUE인가"에 대한 대답은 "예" ;-)라고 생각한다.

언어는 때때로 열거형이 동일한 값에 대해 여러 개의 이름을 갖는 것이 유용하기 때문에 당신을 멈추게 하지 않는다.예를 들면 다음과 같다.

enum compression_method {
    COMP_NONE = 0,
    COMP_LOW = 1,
    COMP_HIGH = 2,
    COMP_BEST = 2,
    COMP_FASTEST = 0,
};

두 개의 다른 열거형 정수가 동일한 정수 값을 가질 수 있는 이유는 무엇인가?

6.7.2.2/3 "누적 지정자"에서 N1265 C99 표준 초안에 명시적으로 허용되기 때문에:

에 대한 열거자 사용=동일한 열거에서 다른 값을 중복하는 값을 가진 열거 상수를 생성할 수 있다.

시스템이 내부적으로 MON과 TUE를 어떻게 구별할 것인가?

나는 그것이 시간 상수(6.6/6 "정수 표현")이기 때문에 불가능하다고 생각한다.그 결과, 다음과 같다.

  • 편찬 후에 다른 것으로 수정될 수 없다.

  • 그들을 구분할 주소가 없다.C에서 열거값의 메모리 위치

    컴파일 시간 상수는 당신이 수정할 수 없는 것에는 주소를 사용할 수 없기 때문에 어떤 주소도 필요하지 않다.

GCC는 단순히 열거형 구성원의 사용을 컴파일 시 조립의 즉각적인 값으로 대체한다.고려 사항:

#include <stdio.h>

enum E {
    E0 = 0x1234,
    E1 = 0x1234
};
int i = 0x5678;

int main() {
    printf("%d\n", E0);
    printf("%d\n", E1);
    printf("%d\n", i);
    return 0;
}

GCC 4.8 x86_64로 컴파일 및 디컴파일:

gcc -c -g -O0 -std=c89 main.c
objdump -Sr main.o

출력에 포함되는 내용:

    printf("%d\n", E0);
   4:       be 34 12 00 00          mov    $0x1234,%esi
  ...
    printf("%d\n", E1);
  18:       be 34 12 00 00          mov    $0x1234,%esi
  ...
    printf("%d\n", i);
  2c:       8b 05 00 00 00 00       mov    0x0(%rip),%eax        # 32 <main+0x32>
                    2e: R_X86_64_PC32       i-0x4
  32:       89 c6                   mov    %eax,%esi

그래서 우리는 다음과 같이 본다.

  • 열거된 회원들은 즉시 사용되어진다.$0x1234그래서 그들이 어디서 왔는지 아는 것은 불가능하다.
  • 변수i그러나 기억에서 우러나온다.0x0(%rip)(이전 예정) 두 변수를 주소별로 구분할 수 있도록

단지 다른 답변들을 보완하기 위해, 나는 당신에게 주어진 다른 열거에 대해 같은 값을 어떻게 사용하는지에 대한 실용적인 예를 제시하겠다.enum널리 유용하다:

enum slots_t {
    SLOT_FIRST = 0,
    SLOT_LEFTARM = SLOT_FIRST,
    SLOT_RIGHTARM = 1,
    SLOT_TORSO = 2,
    SLOT_LEFTLEG = 3,
    SLOT_RIGHTLEG = 4,
    SLOT_LAST = SLOT_RIGHTLEG
};

그러면 코드대로 할 수 있다.

for (int i = SLOT_FIRST; i <= SLOT_LAST; ++i) { }

마치 철학적(또는 그렇지 않은) 것 같다.

#define ZILCH 0
#define NADA  0

서로 다른 이름을 갖는 것이 같은 숫자로 귀결되는 것이 말이 되는 많은 용도가 있다.

열거 상수의 이름은 실제 값 자체가 아니라 값을 할당하는 데 사용된다.만약 당신이 오늘 0 값을 할당한다면, 출력 값은 0이 될 것이다.그리고 예, MON과 TUE 모두 값이 0이고 나머지 값은 WED=1 THU=2 등으로 할당된다.

참조URL: https://stackoverflow.com/questions/11412516/why-can-two-different-enum-enumeration-constants-have-the-same-integer-value

반응형