C'deki bir enumun büyüklüğü nedir?


140

Bir dizi numaralandırma değerleri oluşturuyorum, ancak her bir numaralandırma değeri 64 bit genişliğinde olması gerekir. Doğru hatırlıyorsam, bir enum genellikle int ile aynı boyuttadır; ama bir yerde okuduğumu düşündüm (en azından GCC'de) derleyicinin enum değerlerini tutmak için ihtiyaç duydukları herhangi bir genişliği yapabilir. Peki, 64 bit genişliğinde bir numaraya sahip olmak mümkün mü?


1
İyi anlarsam, 2 ^ 32 numaralandırma sizin için yeterli değil mi? Yoksa bu bir hizalama meselesi, neden 32 yerine 64 olması gerekiyor, çok merak ediyorum.
jokoon

1
@jokoon: Dürüst olmak gerekirse artık hatırlamıyorum. Ben enums 2 ^ 32-1 daha büyük değerler içermesini istedim düşünüyorum.
mipadi

Bir kullanım, bir numaralandırma ve bir işaretçi arasında birleşmeye ihtiyacınız varsa olurdu.
Demi

Yanıtlar:


97

An enumsadece intdeğerleri tutacak kadar büyük olmalıdır . Derleyici, tanımlanan numaralandırma sabitlerine dayalı olarak kullanılan gerçek türü seçmekte serbesttir, böylece tanımladığınız değerleri temsil edebiliyorsa daha küçük bir tür seçebilir. Birine uymayan numaralandırma sabitlerine ihtiyacınız varsa, bunu yapmak intiçin derleyiciye özgü uzantıları kullanmanız gerekir.


12
İlk cümleniz sonuncunuzla çelişiyor gibi görünüyor. A'nın enumbir intveya daha küçük olması gereken sınırlama mı ? @MichaelStum'un cevabını izleyen ilk cümleniz "An'ın enumsadece bir intdeğere uyması garanti edilir ."
HaskellElephant

İkili tamamlayıcı platformlarda çirkin bir uygulamaya duyarlı saldırı (bugünlerde tüm sistemler bu mu?), Negatif değerler içerdiğinden emin olarak bir enum'u int kadar büyük olmaya zorlayabilirsiniz. Yine de önerilen bir teknik değil.
persiflage

7
Bu cevap, bir enumun bir kadar büyük olduğunu göstermektedir int. Michael Stum'un C99'a atıfta bulunan cevabı , bir enumun a kadar küçük olabileceğini söylüyor char.
Frank Kusters

3
Bu cevabın ilk cümlesi yanlış. enumSadece enum en büyük numaralandırıcının değerini tutmak için yeterince büyük olması sağlanır.
MM

91

Mevcut C Standardından (C99) alınmıştır: http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

6.7.2.2 Numaralandırma belirteçleri
[...]
Kısıtlamalar
Bir numaralandırma sabitinin değerini tanımlayan ifade, int olarak temsil edilebilen bir değere sahip bir tamsayı sabit ifade olmalıdır.
[...]
Her numaralandırılmış tür char, işaretli bir tam sayı türü veya bir işaretsiz tam sayı türü ile uyumlu olmalıdır. Tür seçimi uygulama tanımlıdır, ancak sayımın tüm üyelerinin değerlerini temsil edebilmelidir.

Derleyiciler standardı takip etmede iyi değildir, ancak esasen: Enumunuz int'den başka bir şey tutuyorsa, bir veya iki yıl içinde sizi ısırmaya geri dönebilecek derin "desteklenmeyen davranışlar içindesiniz.


3
sadece bu, aşağıdaki geçerli bence geçerli: enum {LAST = INT_MAX, LAST1, LAST2}; bu nedenle LAST2 int'de temsil edilemez, ancak onu tanımlayan bir ifade yoktu.
Johannes Schaub - litb

4
Gerçek PDF'de şunları tanımlar: "Bir numaralandırıcı listesindeki tanımlayıcılar, int [...] türüne sahip sabitler olarak bildirilir". Bunu çok ayrıntılı yapmak için atladım.
Michael Stum

2
Not " Bir imzalı tamsayı türü veya bir işaretsiz tamsayı türü". Mutlaka değil int. shortve longçok türleri tamsayı vardır ve ne olursa olsun uygulama kazma, tüm değerler sığdırmak ( "gerektiğini eder numaralandırma tüm üyelerinin değerlerini temsil etme yeteneğine sahip").

3
Dikkate değer: numaralandırma sabiti ve numaralandırılmış tip aynı şey değildir . Birincisi, numaralandırma listesinin içeriğidir, ikincisi asıl değişkendir. Bu nedenle numaralandırma sabitleri olmakla birlikte int, gerçek numaralandırma değişkeni başka bir tür olabilir. Bu, standartta iyi bilinen bir tutarsızlıktır.
Lundin

1
İÇİN: Lundin bakış açısını netleştirmek için enum my_enum { my_value }, my_valuetip olacak int, ama enum my_enumen azından tüm numaralandırma değerleri temsil etmelidir bir uygulama tanımlı türü olabilir. Dolayısıyla my_value, daraltma dönüşümü olabilir enum my_enum, ancak taşmaması garanti edilir.
P O'Conbhui

17

Önceki cevaplar doğru olsa da, bazı derleyiciler standardı kırma ve tüm değerleri içerecek en küçük türü kullanma seçeneklerine sahiptir.

GCC ile örnek ( GCC Kılavuzundaki belgeler ):

enum ord {
    FIRST = 1,
    SECOND,
    THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )

11
Aslında, gördüğüm kadarıyla bu standardı bozmuyor. Michael Stum'un cevabında açıklandığı gibi, standart, tüm değerlerin uyduğu sürece derleyicinin gerçek numaralandırma türünü seçmesine izin verir.
sleske

2
Onları daha küçük tiplerde saklamak için bir numaralandırma sınırlı aralıktan yararlanmak MacOS C ++ derleyiciler ile çalıştım. Metrowerks Codewarrior veya XCode olup olmadığını hatırlayamıyorum. Bu C ++ standardı dahilindedir. Genel olarak sizeof (MyEnum) == sizeof (int) olduğunu varsayamazsınız.
persiflage

0

Numaralandırmanın son değerini, numaralandırmayı istediğiniz boyutu yapacak kadar büyük bir değere ayarlayın, o zaman bu boyut olmalıdır:

enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};

2
Bu kod soruyu cevaplayabilse de, sorunun nasıl ve / veya neden çözüldüğü hakkında ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır.
leopar

-1

Bir enumdeğişkenin büyüklüğü üzerinde kontrolümüz yoktur . Tamamen uygulamaya bağlıdır ve derleyici kullanarak bir tamsayı için bir ad saklama seçeneği sunar enum, bu nedenle enumbir tamsayı boyutunu takip eder.


-1

C dilinde, enuma'nın bir int. -fshort-enumsKısa yapmak için bir derleme zamanı seçeneği ( ) vardır (Bu genellikle değerlerin 64K'dan fazla olmaması durumunda kullanışlıdır). Boyutunu 64 bit'e yükseltmek için derleme zamanı seçeneği yoktur.


-6

Bu kodu düşünün:

enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;

Çıktı olarak 4 verecektir. Dolayısıyla enum, içerdiği öğe sayısı ne olursa olsun, boyutu her zaman sabittir.


6
Michael Stum'un cevabı doğrudur. Bu derleyiciye özeldir. IAR EWARM ile kendiniz deneyebilirsiniz. IAR EWARM örneğiniz için 1 gösterir. 255'e kadar öğe varsa, hala 1'i gösterir. 256. öğeyi ekledikten sonra 2'ye kadar gider
43'te desowin

11
Soru C ++ ile ilgili değil.
Michas

4
C ya da C ++ yazmadan önce gerçekleştirilmesi gereken önemli şeyler: Derlenmesi, Standard'a göre yasal olduğu anlamına gelmez. Belirli bir sonuç almanız, Standardın her zaman yapacağınızı veya kodunuzu çalıştırdıklarında diğer kullanıcıların yapacağını ifade ettiği anlamına gelmez. Bunun gibi sorular , belirli bir derleyici / ABI için Standart veya en azından uygulama tanımlı spesifikasyona başvuran bir cevaba ihtiyaç duyar . Bir programı derlemek ve çalıştırmak ve bir günde bir sonuç görmek, bu tür sorular hakkında (ve başka bir şey hakkında çok az) ders vermez.
underscore_d
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.