2014-09-16 6 views
21

, 나는이 실험을하고있다 :열거자를 동일한 열거 형 내의 다른 열거 자로 정의 할 수 있습니까? 호기심을 위해서

enum RxqType 
{ 
    A = (1 << 0), 
    B = (1 << 1), 
    C = (A | B), 
    D = A+B+C 
}; 

열거 C와 D는 앞서 열거의 관점에서 정의된다. 그것은 이상한 일이므로 안전한지 확실하지 않습니다. 나는 구글을 통해 그것에 대한 모범을 찾을 수있다.

괜찮을 것 같다 때 비주얼 C++ 2013는 MinGW에 printf 또는 coutCD. 그러나 표준 준수 여부와 정의되지 않은 동작을 유발하는지 여부에 대해 걱정하고 있습니다.

누구나 표준 준수 및 정의되지 않은 동작에 대한 내 걱정에 답변 할 수 있습니까? 그리고 제가 염려해야 할 것이 있습니까?

+1

C++ std :'enum {d, e, f = e + 2}; 예제에서 ... – PiotrNycz

+0

@PiotrNycz 오, 다음 질문 이전에 표준을 찾아야합니다. –

+0

@PiotrNycz 엄밀히 말하자면, 예제는 규범 적이 지 않습니다. 물론 표준에 규격을 준수하지 않는 사례가 포함되어있을 가능성은 거의 없습니다. – Lundin

답변

21
enum RxqType 
{ 
    A = (1 << 0), 
    B = (1 << 1), 
    C = (A | B), 
    D = A+B+C 
}; 

C 및 C++에서 유효합니다. C 용

:

(C11, 6.2.1p7) "각 열거 상수는 열거 목록에 열거 그 형성의 출현 후에 시작 범위를 갖는다." ++ C 용

".위한 열거 선언의 포인트가 열거 고화질 직후"

(C++ 11 3.3.2p4)

-3

예, 100 % 유효합니다. 사실,이 사실은 인정 받고 있습니다. 이 정의 된 후

enum RxqType 
{ 
    A = (1 << 0), 
    B = (1 << 1), 
    C = (A | B), 
    D = A+B+C 
}; 
+3

"누구나 표준 준수 및 정의되지 않은 동작에 대한 내 걱정에 대답 할 수 있습니까?" – Lundin

5

예, 이것은 초안 C99 표준 섹션 각각 열거 범위에 우리를 알려줍니다 식별자의 6.2.1스코프에 덮여 :

각 열거 상수는 범위가 그 은 열거 자 목록에 정의 된 열거 자의 모양이 표시된 직후부터 시작됩니다.

표준 섹션 ++ 초안 C 말한다 선언
3.3.2 포인트 피복 :

열거 선언에 의 포인트의 식별자 (있는 경우) 직후 어느 그 enum-specifier (7.2) 또는 첫 번째 opaque-enum-declaration (7.2) 중 빠른 날짜가 적용됩니다.

및 완전성을 위해 우리는 절을 6.7.2.2열거 지정자 열거 상수 식에 의해 설정 될 수 있으며, 열거 자체가 상수 표현이다 우리에게 초안 C99 표준의을 갈 수 있습니다.상수 식을 무엇

enumerator: 
    enumeration-constant 
    enumeration-constant = constant-expression 

섹션에 6.6상수 식을 덮여 그것은 열거 상수 또한 정수 상수의 산술 표현식이 일정하게 표현하는 것을 우리에게 알려줍니다.

1

이미 언급했듯이주의해야 할 것이 하나 있습니다. 열거 형을 정의하는 동안 C++에서 이미 선언 된 열거 자의 형식이 정확하지 않을 수 있습니다. 기대하고있다. 당신이 기대처럼

유사한 예를 들어
enum E { 
    a = INT_MAX, 
    b = UINT_MAX, 
}; 
enum E2 { 
    c = a + 1, // okay: a is promoted to unsigned int 
}; 

, 오버로드 확인이 작동하지 않을 수 있습니다 :

char f(int); 
template <typename T> 
char (&f(T))[2]; 

enum E { 
    a = 0, 
    b = sizeof(f(a)), // 1 
}; 
enum E2 { 
    c = sizeof(f(a)), // 2 
}; 

enum E { 
    a = INT_MAX, 
    b = UINT_MAX, 
    c = a + 1, // error: overflow 
}; 

같은 결과, 뭔가이 경우에도 유효하지 않습니다

다소 비 순탄 한 다른 유사한 예가 있습니다.

C의 경우 규칙이 조금 더 간단합니다. C에서 열거 상수의 형식은 열거 형식과 관계가 없으므로 E2조차도 내 예제 인 a + 1이 유효하지 않습니다. 이는 일관성있는 결과를 이끌어냅니다.