출력되는 값은, 원래 저장 가능한 크기의 값만큼 되겠습니다.
예를 들어 1바이트는 unsigned 형식으로 0부터 255까지, 0000_0000부터 1111_1111까지 저장 가능한데
256 = 1_0000_0000을 저장하려고 하면 맨 앞의 1은 잘리고 0000_0000만 저장됩니다.
> Each enumerated type is compatible with one of: char, a signed integer type, or an unsigned integer type. It is implementation-defined which type is compatible with any given enumerated type, but whatever it is, it must be capable of representing all enumerator values of that enumeration.
좀 더 자세히 말하자면, C는 매우 저수준의 언어이기 때문에 enum을 만들어준다고 똑똑하게 "enum에서 적어준 값만 넣을 수 있는 변수" 같은 걸 만들어주지 않습니다. 예를 들어서
enum etype { RED=0, BLUE=1, GREEN=2 };
이렇게 적으면 etype이 "0, 1, 2만 들어갈 수 있는 타입"이 되는 게 아니라는 얘기죠. 대신 컴파일러가 알아서 적당히 "음 0, 1, 2는 반드시 들어갈 수 있어야 하니 무슨 타입이면 될까? int면 되겠네?" 하고, 비록 이름은 etype이지만 내부적으로는 적당한 크기의 정수형으로 구현해 줍니다. (이 "적당한 크기의 정수형"이 무엇인지는 implementation-defined이기 때문에 사용하는 OS나 컴파일러에 따라 바뀔 수 있습니다. 지금 테스트해보니 linux gcc/clang에서는 unsigned int를 쓰는군요. 다른 시스템에서는 더 작은 정수형을 쓸 수도 있습니다.)
그래서 다음과 같은 코드가 가능해집니다.
enum etype e = 5;
이건 "형변환"이라기보다는 그냥 원래 etype이 5까지 충분히 담을 수 있는 크기의 모종의 정수형으로 만들어져서 그 범위의 값을 담을 수 있는 거죠.
하지만 이런 식으로 코드를 짜는 것은 저라면 별로 권하지는 않겠는데 왜냐 하면 다음과 같은 골치아픈 에러가 생길 수 있기 때문이죠.
enum etype { RED=0, BLUE=1, GREEN=2 };
enum etype e;
e = -1;
printf("e = %d sizeof(e) = %zu\n", e, sizeof(e));
if (e > RED)
printf("ERROR!\n");
이 코드는 제 컴퓨터에서 (linux x86-64 gcc) "ERROR!"를 출력합니다. 컴파일러가 etype을 unsigned int로 간주했기 때문이죠. enum의 정의에 0, 1, 2만 넣었기 때문에 컴파일러가 unsigned int를 사용하는 건 합법적입니다. (심지어 -W -Wall을 켜도 아무 경고도 안 뜹니다.)
GREEN을 -2로 바꿔주면 컴파일러가 더 이상 unsigned int를 쓸 수 없기 때문에 ERROR가 찍히지 않습니다.
답변
출력되는 값은, 원래 저장 가능한 크기의 값만큼 되겠습니다.
예를 들어 1바이트는 unsigned 형식으로 0부터 255까지, 0000_0000부터 1111_1111까지 저장 가능한데
256 = 1_0000_0000을 저장하려고 하면 맨 앞의 1은 잘리고 0000_0000만 저장됩니다.
원래는 오버플로우 관련 답변을 달았었는데, 틀린 답변을 단 것 같아서 삭제했습니다.
저는 이렇게 생각했습니다.
감사합니다.
감사합니다.
...
asd가 enum이라는 가정 하에, asd는 최대값인 50을 담을 수 있는 적당한 정수 type으로 간주됩니다. 요즘 사용하는 거의 모든 시스템에서 "50을 담을 수 있는 정수"는 60도 담을 수 있으므로 val = 60은 정상적으로 수행될 수 있습니다.
200은 좀 문제가 있을 수 있습니다. (asd가 signed char일 수도 있으므로...)
http://en.cppreference.com/w/c/language/enum
> Each enumerated type is compatible with one of: char, a signed integer type, or an unsigned integer type. It is implementation-defined which type is compatible with any given enumerated type, but whatever it is, it must be capable of representing all enumerator values of that enumeration.
아 혹시 적절한 타입으로 자동 형 변환이 된다는
아 혹시 적절한 타입으로 자동 형 변환이 된다는 뜻인가요??
...
형변환이라는 말은 좀 여기 쓰기엔 애매한 것 같군요. (무슨 타입에서 무슨 타입으로?)
좀 더 자세히 말하자면, C는 매우 저수준의 언어이기 때문에 enum을 만들어준다고 똑똑하게 "enum에서 적어준 값만 넣을 수 있는 변수" 같은 걸 만들어주지 않습니다. 예를 들어서
enum etype { RED=0, BLUE=1, GREEN=2 };
이렇게 적으면 etype이 "0, 1, 2만 들어갈 수 있는 타입"이 되는 게 아니라는 얘기죠. 대신 컴파일러가 알아서 적당히 "음 0, 1, 2는 반드시 들어갈 수 있어야 하니 무슨 타입이면 될까? int면 되겠네?" 하고, 비록 이름은 etype이지만 내부적으로는 적당한 크기의 정수형으로 구현해 줍니다. (이 "적당한 크기의 정수형"이 무엇인지는 implementation-defined이기 때문에 사용하는 OS나 컴파일러에 따라 바뀔 수 있습니다. 지금 테스트해보니 linux gcc/clang에서는 unsigned int를 쓰는군요. 다른 시스템에서는 더 작은 정수형을 쓸 수도 있습니다.)
그래서 다음과 같은 코드가 가능해집니다.
enum etype e = 5;
이건 "형변환"이라기보다는 그냥 원래 etype이 5까지 충분히 담을 수 있는 크기의 모종의 정수형으로 만들어져서 그 범위의 값을 담을 수 있는 거죠.
하지만 이런 식으로 코드를 짜는 것은 저라면 별로 권하지는 않겠는데 왜냐 하면 다음과 같은 골치아픈 에러가 생길 수 있기 때문이죠.
이 코드는 제 컴퓨터에서 (linux x86-64 gcc) "ERROR!"를 출력합니다. 컴파일러가 etype을 unsigned int로 간주했기 때문이죠. enum의 정의에 0, 1, 2만 넣었기 때문에 컴파일러가 unsigned int를 사용하는 건 합법적입니다. (심지어 -W -Wall을 켜도 아무 경고도 안 뜹니다.)
GREEN을 -2로 바꿔주면 컴파일러가 더 이상 unsigned int를 쓸 수 없기 때문에 ERROR가 찍히지 않습니다.
아 감사합니다
아 감사합니다
댓글 달기