표준에 따라 색상이 설정되어 있습니까?
C ++ 11 및 C ++ 14 표준에서 인용 한 답변 :
[expr.static.cast] / 10
정수 또는 열거 유형의 값은 열거 유형으로 명시 적으로 변환 될 수 있습니다. 원래 값이 열거 값 (7.2) 범위 내에 있으면 값이 변경되지 않습니다. 그렇지 않으면 결과 값이 지정되지 않으며 해당 범위에 속하지 않을 수 있습니다.
열거 형 값 의 범위를 찾아 보자 . [dcl.enum] / 7
기본 유형이 고정 된 열거의 경우 열거 값은 기본 유형의 값입니다.
CWG 1766 이전 (C ++ 11, C ++ 14)
따라서 for data[0] == 100에 대해 결과 값이 지정되고 (*) 정의되지 않은 동작 (UB) 이 포함 되지 않습니다 . 더 일반적으로, 기본 유형에서 열거 유형으로 캐스트 할 때 값이에 data[0]대한 UB로 이어질 수 없습니다 static_cast.
CWG 1766 이후 (C ++ 17) CWG 결함 1766을
참조하십시오 . [expr.static.cast] p10 단락이 강화되었으므로 열거 가능한 범위의 열거 형 범위를 벗어난 값을 열거 형 유형으로 캐스팅하면 UB 를 호출 할 수 있습니다 . data[0]열거 형의 기본 유형이므로 위 의 시나리오에는 적용되지 않습니다 (위 참조).
CWG 1766은 표준에서 결함으로 간주되므로 컴파일러 구현자가 C ++ 11 및 C ++ 14 컴파일 모드에 적용하는 것이 허용됩니다.
(*) char는 너비가 8 비트 이상이어야하지만 필수는 아닙니다 unsigned. 저장 가능한 최대 값 127은 C99 표준의 부록 E 이상이어야 합니다.
[expr] / 4와 비교
표현식을 평가하는 동안 결과가 수학적으로 정의되지 않았거나 해당 유형의 표현 가능한 값 범위에없는 경우 동작이 정의되지 않습니다.
CWG 1766 이전에는 변환 적분 유형-> 열거 유형이 지정되지 않은 값을 생성 할 수 있습니다 . 질문 : 지정되지 않은 값이 해당 유형의 표현 가능한 값을 벗어날 수 있습니까? 대답이 ' 아니요' 라고 답 합니다. 대답이 ' 예' 인 경우 서명 된 유형의 작업에 대해 "이 작업은 지정되지 않은 값을 생성합니다"와 "이 작업은 정의되지 않은 동작을 갖습니다"라는 보장에 차이가 없습니다.
따라서, CWG 1766 이전에도 static_cast<Color>(10000)것 하지 UB 호출; 그러나 CWG 1766 이후 에는 UB를 호출합니다.
이제, switch진술 :
[stmt. 스위치] / 2
조건은 정수 유형, 열거 유형 또는 클래스 유형이어야합니다. [...] 통합 프로모션이 수행됩니다.
[전환 프롬] / 4
prvalue의 범위가 지정되지 않은 기본 형태 고정 (7.2) 열거 타입의 기본 유형의 prvalue로 전환시킬 수있다. 또한, 기본 승격을 기본 유형에 적용 할 수있는 경우 기본 유형이 고정 된 범위가없는 열거 유형의 prvalue를 승격 된 기본 유형의 prvalue로 변환 할 수도 있습니다.
참고 : enum-base 가 없는 범위가 지정된 열거 형의 기본 유형은 입니다 int. 범위가 지정되지 않은 열거 형의 경우 기본 형식은 구현 정의하지만,보다 큰지지 않습니다 int경우 int모든 열거의 값을 포함 할 수 있습니다.
에 대한 범위가 지정되지 않은 열거 ,이 리드 우리 / 1
이외 정수형의 prvalue bool, char16_t, char32_t, 또는 wchar_t그 정수 변환 계수 (4.13) 이하의 순위보다 int형의 prvalue로 전환 될 수 int있는 경우 int, 소스 타입의 모든 값을 나타낼 수있다; 그렇지 않으면 소스 prvalue를 유형의 prvalue로 변환 할 수 있습니다 unsigned int.
범위가 지정되지 않은 열거 의 경우 int여기에서 처리 합니다. 들어 범위의 열거 ( enum class과 enum struct), 더 중요한 홍보는 적용되지 않습니다. 어떤 식 으로든, 저장된 값이 기본 유형의 범위와의 범위에 있기 때문에 통합 승격은 UB로 이어지지 않습니다 int.
[stmt. 스위치] / 5
switch명령문이 실행될 때 해당 조건이 평가되고 각 케이스 상수와 비교됩니다. 대소 문자 상수 중 하나가 조건 값과 같으면 일치하는 case레이블 다음에 나오는 명령문으로 제어가 전달됩니다 . case조건에 일치하는 상수가 없고 default레이블 이있는 경우 레이블로 레이블이 지정된 명령문으로 제어가 전달됩니다 default.
default라벨 이 맞아야합니다.
참고 : 비교 연산자를 다시 살펴볼 수 있지만 참조 된 "비교"에서는 명시 적으로 사용되지 않습니다. 실제로, 우리의 경우 범위가 있거나 범위가 지정되지 않은 열거 형에 UB를 도입한다는 힌트는 없습니다.
보너스로, 표준은 이것과 관련하여 일반 enum을 보장합니까?
enum범위가 지정되어 있는지 여부 는 여기서 차이가 없습니다. 그러나 기본 유형이 고정되어 있는지 여부에 차이가 있습니다. 완전한 [decl.enum] / 7은 다음과 같습니다.
기본 유형이 고정 된 열거의 경우 열거 값은 기본 유형의 값입니다. 그렇지 열거위한 전자 분 작은 열거이고 E 최대가 최대이고, 열거의 값들은 값이 범위에있는 (B)의 분 하는 ㄱ 최대 다음과 같이 정의 :하자가 K있을 12의 보수 표현과 0A의 하나의 보수 또는 부호 크기 표현. b max 는 max (| e min | − K, | e max |) 보다 크거나 같고 2 와 같은 가장 작은 값입니다.M - 1 ,M음이 아닌 정수이다. e min 이 음이 아닌경우 b min 은 0이고,그렇지 않으면 -(b max + ) 입니다.K
다음 열거를 살펴 보겠습니다.
enum ColorUnfixed /* no fixed underlying type */
{
red = 0x1,
yellow = 0x2
}
모든 범위가 지정된 열거 형에는 고정 된 기본 유형이 있으므로이를 범위가 지정된 열거 형으로 정의 할 수 없습니다.
다행히 ColorUnfixed가장 작은 열거자는 red = 0x1이므로 max (| e min | − K, | e max |) 는 | e max | 어쨌든 yellow = 0x2. 최소치 크거나 같음 2동일하다, (2) M - 1 양의 정수가 M있다 3( 2 2 - 1 ). (범위는 1 비트 단위로 범위를 확장하는 것이 목적이라고 생각합니다.) b max is 3및 bmin is 0입니다.
따라서, 100범위를 벗어난 것 ColorUnfixed, 및이 static_castCWG 후 1,766 1,766 CWG 전에 불특정 값 및 정의되지 않은 동작을 생성한다.
char이므로 "원래 값이 열거 값 (7.2) 범위 내에 있으면 값이 변경되지 않습니다." 적용됩니다.