Ich erstelle eine Reihe von Enum-Werten, aber jeder Enum-Wert muss 64 Bit breit sein. Wenn ich mich richtig erinnere, hat ein Enum im Allgemeinen die gleiche Größe wie ein Int; aber ich dachte, ich hätte irgendwo gelesen, dass der Compiler (zumindest in GCC) die Aufzählung beliebig breit machen kann, um ihre Werte zu halten. Ist es also möglich, eine Aufzählung mit einer Breite von 64 Bit zu haben?
Wie groß ist eine Aufzählung in C?
Michael Stumm
Entnommen aus der aktuellen C-Norm (C99): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
6.7.2.2 Aufzählungsbezeichner
[…]Einschränkungen
Der Ausdruck, der den Wert einer Aufzählungskonstante definiert, muss ein ganzzahliger konstanter Ausdruck sein, der einen als int darstellbaren Wert hat.
[…]Jeder Aufzählungstyp muss mit char, einem vorzeichenbehafteten ganzzahligen Typ oder einem vorzeichenlosen ganzzahligen Typ kompatibel sein. Die Wahl des Typs ist implementierungsdefiniert, muss aber in der Lage sein, die Werte aller Mitglieder der Enumeration darzustellen.
Nicht, dass Compiler gut darin wären, dem Standard zu folgen, aber im Wesentlichen: Wenn Ihre Enum etwas anderes als ein Int enthält, befinden Sie sich in einem tiefen “nicht unterstützten Verhalten, das Sie in ein oder zwei Jahren beißen kann”.
Update: Der neueste öffentlich verfügbare Entwurf des C-Standards (C11): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf enthält dieselben Klauseln. Daher gilt diese Antwort immer noch für C11.
-
Wenn ich nur das habe, gilt Folgendes, denke ich: enum { LAST = INT_MAX, LAST1, LAST2 }; also ist LAST2 nicht in int darstellbar, aber es gab keinen Ausdruck, der es definierte.
– Johannes Schaub – litb
14. Dezember 2008 um 1:33 Uhr
-
Im eigentlichen PDF definiert es Folgendes: “Die Bezeichner in einer Aufzählungsliste werden als Konstanten deklariert, die den Typ int haben[…]”. Ich habe das weggelassen, um es nicht zu ausführlich zu machen.
– Michael Stumm
♦14. Dezember 2008 um 1:36 Uhr
-
Notiz “a vorzeichenbehafteter ganzzahliger Typ oder ein unsigned integer type”. Nicht notwendigerweise
int
.short
undlong
sind auch Integer-Typen, und was auch immer die Implementierung auswählt, alle Werte müssen passen (“soll in der Lage sein, die Werte aller Mitglieder der Enumeration darzustellen”).– Benutzer824425
18. Februar 2016 um 17:45 Uhr
-
Bemerkenswert: Aufzählungskonstante und aufgezählter Typ ist nicht dasselbe. Ersteres ist der Inhalt der Enum-Deklarationsliste, letzteres ist die eigentliche Variable. Während also die Enumeration konstant sein muss
int
, könnte die tatsächliche Aufzählungsvariable einen anderen Typ haben. Dies ist eine bekannte Inkonsistenz im Standard.– Ludin
25. September 2017 um 11:56 Uhr
-
Um Lundins Argument zu verdeutlichen: Für
enum my_enum { my_value }
,my_value
wird Typ habenint
aberenum my_enum
kann einen implementierungsdefinierten Typ haben, der mindestens alle Enumerationswerte darstellen muss. Somy_value
kann eine verengende Konvertierung zu habenenum my_enum
aber es läuft garantiert nicht über.– P O’Conbhui
26. November 2017 um 16:41 Uhr
Robert Glück
Ein enum
ist nur garantiert groß genug, um zu halten int
Werte. Der Compiler kann den tatsächlich verwendeten Typ basierend auf den definierten Aufzählungskonstanten frei wählen, sodass er einen kleineren Typ auswählen kann, wenn er die von Ihnen definierten Werte darstellen kann. Wenn Sie Aufzählungskonstanten benötigen, die nicht in eine passen int
Sie müssen dazu Compiler-spezifische Erweiterungen verwenden.
-
Dein erster Satz scheint deinem letzten zu widersprechen. Ist die Einschränkung, dass eine
enum
sollte größer als ein seinint
oder kleiner? Nach der Antwort von @MichaelStum sollte Ihr erster Satz “Anenum
passt garantiert nur in eineint
Wert.”– HaskellElephant
20. Juni 2014 um 9:23 Uhr
-
Als hässlicher Implementierungs-sensibler Hack auf Zweierkomplement-Plattformen (sind das heutzutage alle Systeme?) können Sie eine Aufzählung zwingen, so groß wie ein Int zu sein, indem Sie sicherstellen, dass sie negative Werte enthält. Allerdings keine empfehlenswerte Technik.
– Persiflage
23. September 2016 um 19:37 Uhr
-
Diese Antwort scheint darauf hinzudeuten, dass eine Aufzählung so groß ist wie eine
int
. Die Antwort von Michael Stum, die sich auf C99 bezieht, besagt, dass eine Aufzählung so klein wie a sein kannchar
.– Frank Küster
15. September 2017 um 6:46 Uhr
-
Der erste Satz dieser Antwort ist falsch. Das
enum
ist nur garantiert groß genug, um den Wert des größten Enumerators in der Enumeration aufzunehmen.– MM
28. September 2018 um 8:11 Uhr
-
@MM, er wollte maximal halten
int
Werte. Es ist eine richtige Aussage. Deine Aussage ist eigentlich falsch. Einenum
enthält nicht den größten Enumerator, wenn dieser Enumerator größer als an istint
. Ich habe das gelernt, indem ich meinen 64-Bit-Enumerator auf das Maximum von gekürzt habeint
(was in meinem Fall 32-Bit ist).– SO_fix_the_vote_sorting_bug
5. Juni 2021 um 13:57 Uhr
Kevin Cox
Während die vorherigen Antworten richtig sind, haben einige Compiler die Möglichkeit, den Standard zu brechen und den kleinsten Typ zu verwenden, der alle Werte enthält.
Beispiel mit GCC (Dokumentation im das GCC-Handbuch):
enum ord {
FIRST = 1,
SECOND,
THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )
-
Eigentlich, soweit ich das sehen kann, bricht das nicht den Standard. Wie in der Antwort von Michael Stum erläutert, erlaubt der Standard dem Compiler, den tatsächlichen Typ der Aufzählungen auszuwählen, solange alle Werte passen.
– schleske
7. September 2015 um 10:27 Uhr
-
Ich habe mit MacOS C++-Compilern gearbeitet, die den begrenzten Wertebereich in einer Aufzählung ausnutzen, um sie in kleineren Typen zu speichern. Ich kann mich nicht erinnern, ob es Metrowerks Codewarrior oder XCode war. Dies ist innerhalb des C++-Standards. Sie können nicht generell sizeof(MyEnum) == sizeof(int) annehmen.
– Persiflage
23. September 2016 um 19:29 Uhr
Scirdan
Setzen Sie einfach den letzten Wert der Aufzählung auf einen Wert, der groß genug ist, um die gewünschte Größe der Aufzählung zu erreichen, sie sollte dann diese Größe haben:
enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};
Mike
Wir haben keine Kontrolle über die Größe von an enum
Variable. Es hängt vollständig von der Implementierung ab, und der Compiler bietet die Möglichkeit, einen Namen für eine Ganzzahl mit zu speichern enum
Also enum
folgt der Größe einer ganzen Zahl.
SS Anne
In C-Sprache, an enum
hat garantiert die Größe eines int
. Es gibt eine Option zum Kompilieren (-fshort-enums
), um es so kurz zu machen (Dies ist hauptsächlich nützlich, wenn die Werte nicht mehr als 64 KB betragen). Es gibt keine Option zur Kompilierzeit, um die Größe auf 64 Bit zu erhöhen.
SS Anne
Betrachten Sie diesen Code:
enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;
Es wird 4 als Ausgabe geben. Also egal die Anzahl der Elemente an enum
enthält, ist seine Größe immer fest.
-
Die Antwort von Michael Stum ist richtig. Dies ist Compiler-spezifisch. Mit IAR EWARM können Sie es selbst ausprobieren. IAR EWARM zeigt 1 für Ihr Beispiel. Wenn es bis zu 255 Elemente gibt, wird immer noch 1 angezeigt. Nach dem Hinzufügen des 256. Elements steigt es auf 2.
– desowin
25. November 2015 um 7:43 Uhr
-
Die Frage bezieht sich nicht auf C++.
– Michas
31. August 2016 um 23:12 Uhr
-
Wichtige Dinge, die Sie wissen sollten, bevor Sie weiter C oder C++ schreiben: Nur weil es kompiliert werden kann, heißt das nicht, dass es gemäß dem Standard legal ist. Nur weil Sie ein bestimmtes Ergebnis erhalten, bedeutet das nicht, dass der Standard besagt, dass Sie dies immer tun werden oder dass andere Benutzer dies tun werden, wenn sie Ihren Code ausführen. Fragen wie diese erfordern eine Antwort, die sich auf die Norm bezieht oder wenigstens implementierungsdefinierte Spezifikation für einen bestimmten Compiler/ABI. Einfach ein Programm zu kompilieren und auszuführen und an einem Tag ein Ergebnis zu sehen, vermittelt keine Lektion über solche Fragen (und sehr wenig über irgendetwas anderes).
– Unterstrich_d
16. September 2018 um 16:20 Uhr
Also, wenn ich es gut verstehe, reichen Ihnen 2 ^ 32 Enums nicht aus? Oder ist es ein Ausrichtungsproblem, warum brauchen Sie diese 64 statt 32, ich bin sehr neugierig.
– Jokon
6. Mai 2012 um 14:27 Uhr
@jokoon: Ich erinnere mich ehrlich gesagt nicht mehr. Ich glaube, ich wollte, dass die Aufzählungen Werte enthalten, die größer als 2^32-1 sind.
– Mipadi
4. Januar 2013 um 17:37 Uhr
Eine Verwendung wäre, wenn Sie eine Vereinigung zwischen einer Aufzählung und einem Zeiger benötigen.
– Demi
21. Dezember 2013 um 1:03 Uhr
Eine wichtige Überlegung in der Größe von
enum
ist in der Tat Speichernutzung. Ist die Speicheroptimierung tot oder so, oder denken alle, dass der Compiler immer noch das Zentrum des Universums ist und automatisch alles schnell und optimal macht, ohne dass sich der Programmierer anstrengen muss? Es ist absurd, einen größeren Datentyp zu verwenden, als Sie benötigen, und wenn ich nur 256 Werte oder weniger für meine Aufzählung benötige, warum brauche ich dann 16- oder 32-Bit-Wörter, um sie zu speichern? (Das Datenmodell ist keine Entschuldigung. Die Werte werden normalerweise recht einfach vorzeichenerweitert, z. B. wenn sie in den Registern gespeichert werden.)– AMDG
5. Mai 2021 um 18:17 Uhr