PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Größe von Enums in C++


Neomi
2005-06-01, 14:03:55
Bisher habe ich nur recht selten mal Enums benutzt, stattdessen die guten alten Integer und dazu benannte Konstanten per #define. Es gibt da eine Sache, die mich bisher noch von Enums abhält, vielleicht weiß jemand hier eine Lösung.

Erstmal möchte ich keinen Speicher verschwenden, also keine 4 Byte für einen Enum, der sich locker mit einem einzelnen Byte begnügen könnte. Das summiert sich ja ziemlich auf, wenn man viele davon nutzt. Im Hauptspeicher direkt wäre das noch verschmerzbar, für die Nutzung von Strukturen in Dateien aber unpraktisch. Eine Struktur zum Laden und Speichern, eine zur eigentlichen Nutzung und dann mit Castings zwischen den beiden kopieren ist nicht die Vereinfachung, die ein Enum bieten soll. Variablen passender Größe bei jeder Nutzung zum passenden Enum umcasten ist auch nicht toll, dann kann man auch gleich drauf verzichten.

Und jetzt die eigentliche Frage:
Wie kann ich (in standardkonformem C++) pro Enum festlegen, in was für einem Datentyp (signed/unsigned char/short/long) er im Speicher hinterlegt wird? Oder ist er grundsätzlich 4 Byte groß?

Gast
2005-06-01, 14:30:55
Soweit ich das jetzt kapiert habe, benutzt er immer integers um die Werte zuzuordnen.

Also bleibt es wohl bei 4 Byte.

Gast
2005-06-01, 14:36:14
Wie viele Element soll denn deine Aufzählung enthalten? Eine sinnvolle Verwendung von Enumerationen sehe ich eher in wenigen Elementen, wie z.B. Wochentage, Monate oder Farben. Wenn du so viele Elemente hast, dass du dir schon über die Größe Gedanken machst, würde ich eher ein Array verwenden. Casten kann man Enums imo sowieso nur nach Int.

maximAL
2005-06-01, 15:33:32
äh, ein enum ist nur ein wert.
beispiel.

class MyClass
{
enum X{a,b,c,d,e,f};
X MyX;
};

ist genau 4 byte groß und nicht 24 (6*4byte);
die verschiedenen namen für X definieren nur, welche werte man auf eine instanz des enums packen kann. MyX ist trotzdem nur 4 byte (ein int) groß.
und um sich über 4 byte gegenüber 1 byte gedanken zu machen, sollte man schon verdammt gute gründe haben :rolleyes:

Coda
2005-06-01, 16:26:46
Neomi die Speicherersparnis ist hier völlig fehl am Platz. Man sollte bei modernen CPUs mindestens ein Alignment von 4 Bytes einhalten.

micki
2005-06-01, 16:44:33
Neomi die Speicherersparnis ist hier völlig fehl am Platz. Man sollte bei modernen CPUs mindestens ein Alignment von 4 Bytes einhalten.
ihm geht es um dateien, nicht so sehr ums ram, schrieb er jedenfalls. und da ist es schon ein unterschied ob man 1byte oder 4bytes nutzt. im ram wären 4bytes natürlich besser.


@neomi
wenn du speicher sparen möchtest, geht sowas:


enum EABC
{
EABCSIZE=2,
t1,t2,t3,
};

class CABC
{
EABC a:EABCSIZE;
EABC b:EABCSIZE;
EABC c:EABCSIZE;
EABC d:EABCSIZE;
EABC e:EABCSIZE;
EABC f:EABCSIZE;
EABC g:EABCSIZE;
EABC h:EABCSIZE;
EABC i:EABCSIZE;
EABC j:EABCSIZE;
EABC k:EABCSIZE;
EABC l:EABCSIZE;
EABC m:EABCSIZE;
EABC n:EABCSIZE;
EABC o:EABCSIZE;
EABC p:EABCSIZE;
};


sizeof(CABC) wäre eigentlich 64, aber mit dem : operator sind es 4bytes.

MfG
micki

Neomi
2005-06-01, 18:11:18
Danke erstmal, aber leider hilft davon nichts wirklich. Ich habe mich da wohl ein wenig zu ungenau ausgedrückt.

@Gast (1):

Das habe ich befürchtet, nachdem ich selbst keine Möglichkeit gefunden habe.

@Gast (2):

Die Zahl der Elemente eines Enums ist doch völlig egal. Ich wüßte jetzt nicht, was das mit einem Array zu tun haben sollte.

@maximAL:

Mir ist völlig klar, daß ein Enum nur ein einziger Wert ist, egal wie viele Ausprägungen möglich sind. Mit der Aufsummierung meinte ich viele Enums, nicht viele Ausprägungen eines Enums. Mein Problem ist nur die Größe der einen Variable, die der Enum belegt.

@Coda:

Speicher sparen auf Kosten der Geschwindigkeit ist nicht verkehrt, wenn der Flaschenhals an der richtigen Stelle sitzt. Sicher, bei einzelnen Enums einer State Machine sind die paar Bytes egal, bei anderen Anforderungen sind sie aber doch wichtig. Ich achte auf ein Alignment von 1 Byte bei 1 Byte großen Werten, 2 Byte bei 2 Byte großen Werten, 4 Byte bei allem darüber.

@micki:

Das ist zwar gut, um kleine Integerwerte in einem Flagregister mit unterzubringen, einzelne Enums bekommt man damit aber leider nicht unter 4 Bytes.

Mal ein kleines Beispiel zu dem eigentlichen Problem, dem Datenaustausch mit Dateien:

typedef unsigned char uchar;
typedef unsigned short ushort;

#pragma pack (push, pack_tga, 1)

struct TgaHeader
{
uchar IDLength;
uchar ColorMapType;
uchar ImageType;

struct
{
ushort FirstEntryIndex;
ushort ColorMapLength;
uchar ColorMapEntrySize;
} ColorMapSpecification;

struct
{
ushort xOrigin;
ushort yOrigin;
ushort Width;
ushort Height;
uchar PixelDepth;
uchar ImageDescriptor;
} ImageSpecification;
};

#pragma pack (pop, pack_tga)

#define TGA_IMAGETYPE_COLORMAPPED 1
#define TGA_IMAGETYPE_TRUECOLOR 2
#define TGA_IMAGETYPE_GRAYSCALE 3
#define TGA_IMAGETYPE_COLORMAPPED_RLE 9
#define TGA_IMAGETYPE_TRUECOLOR_RLE 10
#define TGA_IMAGETYPE_GRAYSCALE_RLE 11

Hier würde sich ImageType ja geradezu als Enum anbieten, leider wird dadurch dann die Struktur zerrissen und man kann keine validen TGA-Dateien mehr lesen oder schreiben. Hätte ich hier einen 1 Byte großen Enum, würde der Debugger mir immer gleich die Bedeutung des Wertes anzeigen, nicht bloß eine Zahl zum selber nachschlagen. Programmtechnisch sollte es nicht den geringsten Unterschied machen, Enums sind alleine ein Komfortfeature für Programmierer. Wenn Enums aber grundsätzlich 4 Byte groß sind, sind sie in solchen Situationen schlicht unbrauchbar.