Wie groß ist eine Aufzählung in C?

Lesezeit: 7 Minuten

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?

  • 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


Benutzeravatar von Michael Stum
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 und long 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 haben intaber enum my_enum kann einen implementierungsdefinierten Typ haben, der mindestens alle Enumerationswerte darstellen muss. So my_value kann eine verengende Konvertierung zu haben enum my_enumaber es läuft garantiert nicht über.

    – P O’Conbhui

    26. November 2017 um 16:41 Uhr


Benutzeravatar von Robert Gamble
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 sein int oder kleiner? Nach der Antwort von @MichaelStum sollte Ihr erster Satz “An enum passt garantiert nur in eine int 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 kann char.

    – 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. Ein enum enthält nicht den größten Enumerator, wenn dieser Enumerator größer als an ist int. Ich habe das gelernt, indem ich meinen 64-Bit-Enumerator auf das Maximum von gekürzt habe int (was in meinem Fall 32-Bit ist).

    – SO_fix_the_vote_sorting_bug

    5. Juni 2021 um 13:57 Uhr

Benutzeravatar von Kevin Cox
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

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

Mikes Benutzeravatar
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 enumAlso enum folgt der Größe einer ganzen Zahl.

Benutzeravatar von SS Anne
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.

Benutzeravatar von SS Anne
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

1424520cookie-checkWie groß ist eine Aufzählung in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy