2014-09-16 92 views
21

, bu deney yaşıyorum:Bir numaralandırıcı aynı enum türündeki diğer sayımcılar açısından tanımlanabilir mi? merakı uğruna

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

Listeleyicisi C ve D daha önce enumerator'ın açısından tanımlanır. Bu sıradışı çünkü güvenli olup olmadığından emin değilim. Google ile ilgili hiçbir örnek bulamıyorum (belki de gözden kaçırmayın).

Her şey yolunda görünüyor zaman, Visual C++ 2013 ve MinGW üzerinde printf veya coutC ve D. Ama standart uygun olup olmadığını ve tanımlanmamış davranışları tetikleyip tetiklemediğini merak ediyorum.

Standart uyumluluk ve tanımlanmamış davranışlar hakkındaki endişelerime cevap verenler var mı? Ve endişelenmem gereken başka bir şey var mı?

+1

C++ std: 'enum {d, e, f = e + 2} 'den bir örnek;' ... – PiotrNycz

+0

@PiotrNycz Oh, bir sonraki sorudan önce standardı (ları) incelemeyi hatırlamalıyım. –

+0

@PiotrNycz Kesin olarak, örnekler normatif değildir. Elbette standardın uyumlu olmayan örnekler içermesi olası değildir. – Lundin

cevap

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

C ve C++ 'da bu geçerlidir. : C

:

(C11, 6.2.1p7) "Her numaralandırma sabit sadece sayimm listedeki tanımlama numaralayıcısı görünümünü sonra başlar kapsamı vardır." C++ için

: "bir numaralandırma için beyan noktası, Numaralayıcı-tanımı hemen sonra bir"

(C++ 11, 3.3.2p4)

-3

Evet,% 100 geçerli. Bu gerçekten iyi, aslında, takdir. o belirlendikten sonra

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

"Standart uygunluk ve tanımlanmamış davranış hakkında endişelerimi cevaplayan herkes var mı?" – Lundin

5

Evet, bu taslak C99 standart bölümde her numaralayıcı kapsamı içindedir söyler hangi tanımlayıcılar ait 6.2.1Kapsamları kaplıdır:

Her numaralandırma sabiti kapsamı vardır o , bir numaralandırma listesindeki tanımlayan numaralandırıcının hemen görünmesinden sonra başlar.

Bu

standart bölüm ++ taslak C der beyan
arasında 3.3.2 noktası kaplıdır:

bir numaralandırma için beyan noktası tanımlayıcı (eğer varsa) hemen sonra ya onun hangisi önce gelirse enum-specifier (7.2) veya ilk opak-enum-declaration (7.2).

ve bütünlüğü uğruna biz bölümüne 6.7.2.2Sayım belirteçleri sayimm sabit ifadeye göre ayarlanabilir ve bir enumerator kendisi sabit bir ifadesidir söyler taslak C99 standardının gidebilir.Sabit ifadesini nelerdir

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

bölümünde 6.6Sabit ifadeleri kaplıdır ve enumerator'ın sabitleri ve ayrıca tamsayı sabitler bu aritmetik ifadeler de sabit ifadeler nelerdir olduğunu söyler.

1

Daha önce de belirtildiği gibi, tam olarak geçerli olmakla birlikte, dikkat etmeniz gereken bir şey vardır: bir numaralandırma türü tanımlanırken, C++ olarak, önceden bildirilmiş sayıcılar tam türünüze sahip olmayabilir. bekliyor. beklediğiniz gibi

benzer Örneğin
enum E { 
    a = INT_MAX, 
    b = UINT_MAX, 
}; 
enum E2 { 
    c = a + 1, // okay: a is promoted to unsigned int 
}; 

, aşırı yük çözünürlük davranabilir değil:

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 
}; 

gibi bir sonucu olarak, bir şey bu olsa bile geçerli değil

Bir şekilde anlamsız olan benzer başka örnekler de var.

C için kurallar biraz daha basittir. C'de, bir numaralandırma sabiti türü, numaralandırma türünden bağımsızdır, bu nedenle a + 1 örneğim, E2 ile bile geçersizdir. Bu, tutarlı sonuçlar doğuruyor.

İlgili konular