Problem mit enum und unsigned
-
typedef enum {leer = 0, weisserBauer = 1, weisserTurm = 2, weisserSpringer = 3, weisserLaeufer = 4, weisseDame = 5, weisserKoenig = 6, schwarzerBauer = 7, schwarzerTurm = 8, schwarzerSpringer = 9, schwarzerLaeufer = 10, schwarzeDame = 11, schwarzerKoenig = 12 } Figur; // 12 Figuren brauchen 4 Bit: 2^4 = 16 ostream& operator<<(ostream& out, Figur figur) { switch (figur) { case weisserBauer: out << "wB"; break; case weisserTurm: out << "wT"; break; case weisserSpringer: out << "wS"; break; case weisserLaeufer: out << "wL"; break; case weisseDame: out << "wD"; break; case weisserKoenig: out << "wK"; break; case schwarzerBauer: out << "sB"; break; case schwarzerTurm: out << "sT"; break; case schwarzerSpringer: out << "sS"; break; case schwarzerLaeufer: out << "sL"; break; case schwarzeDame: out << "sD"; break; case schwarzerKoenig: out << "sK"; break; } return out; } struct Zug { unsigned weisserSpielerAmZug : 1; unsigned von : 6; // 2^6 = 64 Felder unsigned zu : 6; // 2^6 = 64 Felder Figur ziehendeFigur : 4; Figur geschlageneFigur : 4; };Wenn ich jetzt einen Zug zug{1, 0, 1, schwarzerSpringer, leer}; erstelle und
ostream& operator<<(ostream& out, Figur figur) mit figur == zug; aufrufe, hat er im Debugger den Wert "-7" (obwohl da unsigned steht) und das switch im operator<< wird übersprungen. Wenn ich im operator<< "switch ((unsigned)figur)" schreibe, hilft das nichts.Wer kann mir helfen?
-
Folgendes (sehr unelegant, und funktioniert nicht mit "schwarzerTurm") hat geholfen:
typedef enum {leer = 0, weisserBauer = 1, weisserTurm = 2, weisserSpringer = 3, weisserLaeufer = 4, weisseDame = 5, weisserKoenig = 6, schwarzerBauer = 7, schwarzerTurm = 8, schwarzerSpringer = -7, schwarzerLaeufer = -6, schwarzeDame = -5, schwarzerKoenig = -4 } Figur; // 12 Figuren brauchen 4 Bit: 2^4 = 16
-
Klappt
unsigned ziehendeFigur : 4;
?
-
Anscheinend ja!

-
Wenn man mal das ostream außen vor lässt, sieht mir der Code schon sehr stark nach C aus ("typedef enum" schreibt man unter C++ eigentlich nicht). Falls der Compiler schon C++11 unterstützt, kann man auch den zugrunde liegenden Integertyp des Enums setzen (Standard ist int).
Beispiel:
enum Figur : unsigned int { leer = 0, weisserBauer = 1, weisserTurm = 2, weisserSpringer = 3, weisserLaeufer = 4, weisseDame = 5, weisserKoenig = 6, schwarzerBauer = 7, schwarzerTurm = 8, schwarzerSpringer = 9, schwarzerLaeufer = 10, schwarzeDame = 11, schwarzerKoenig = 12 };Des Weiteren ist mir die verwendete Syntax innerhalb der Struktur vollkommen unbekannt (<typ> <bezeichner> : <wert> kenne ich jetzt nicht überhaupt nicht von C++).
-
asc schrieb:
Des Weiteren ist mir die verwendete Syntax innerhalb der Struktur vollkommen unbekannt (<typ> <bezeichner> : <wert> kenne ich jetzt nicht überhaupt nicht von C++).
Das ist vollkommen gültiges C++, wenn auch nicht mehr so häufig genutzt.
Die Syntax wird für Bitfelder genutzt.struct Zug { unsigned weisserSpielerAmZug : 1; // 1 Bit unsigned von : 6; // 6 Bit unsigned zu : 6; // 6 Bit Figur ziehendeFigur : 4; // 4 Bit Figur geschlageneFigur : 4; // 4 Bit };Allerdings sollte man schon extrem driftige Gründe haben, obiges zu schreiben.
struct Zug { unsigned char weisserSpielerAmZug; // 8 Bit (bzw. CHAR_BIT Bit, um genau zu sein) unsigned char von; // -||- unsigned char zu; // -||- Figur ziehendeFigur; // hängt vom Compiler ab Figur geschlageneFigur; // -||- };Diese modifizierte Variante ist zwar größer, dafür aber wesentlich schneller,
da der Compiler hier nicht mit Bitshifts rumhantieren muss.Noch besser wäre:
struct Zug { Figur ziehendeFigur; // hängt vom Compiler ab Figur geschlageneFigur; // -||- unsigned char weisserSpielerAmZug; // 8 Bit (bzw. CHAR_BIT Bit, um genau zu sein) unsigned char von; // -||- unsigned char zu; // -||- };sizeof(Figur) kann theoretisch größer als 1 werden. Wenn die beiden Figuren nach den unsigned char's kommen, fügen die meisten Compiler standardmäßig ein Füllbyte ein, was durch richtige Sortierung vermieden wird.
-
DrakoXP schrieb:
Noch besser wäre:
struct Zug { Figur ziehendeFigur; // hängt vom Compiler ab Figur geschlageneFigur; // -||- unsigned char weisserSpielerAmZug; // 8 Bit (bzw. CHAR_BIT Bit, um genau zu sein) unsigned char von; // -||- unsigned char zu; // -||- };sizeof(Figur) kann theoretisch größer als 1 werden. Wenn die beiden Figuren nach den unsigned char's kommen, fügen die meisten Compiler standardmäßig ein Füllbyte ein, was durch richtige Sortierung vermieden wird.
Falsch. Es wird hier nur verschoben ans Ende.
struct Zug { unsigned char weisserSpielerAmZug; unsigned char von; unsigned char zu; char padding; Figur ziehendeFigur; Figur geschlageneFigur; };struct Zug { Figur ziehendeFigur; Figur geschlageneFigur; unsigned char weisserSpielerAmZug; unsigned char von; unsigned char zu; char padding; };Wenn sizeof(Figur)==4 oder mehr wird, dann kann man langsam Speicher verschwenden durch noch ungeschicktere Reihenfolge.
-
aaaaaaaaaaaa schrieb:
Folgendes (sehr unelegant, und funktioniert nicht mit "schwarzerTurm") hat geholfen:
typedef enum {leer = 0, weisserBauer = 1, weisserTurm = 2, weisserSpringer = 3, weisserLaeufer = 4, weisseDame = 5, weisserKoenig = 6, schwarzerBauer = 7, schwarzerTurm = 8, schwarzerSpringer = -7, schwarzerLaeufer = -6, schwarzeDame = -5, schwarzerKoenig = -4 } Figur; // 12 Figuren brauchen 4 Bit: 2^4 = 16Ich würde nur den ersten Wert explizit vergeben (z.B. -7), der Rest ergibt sich automatisch (der Wert für schwarzerTurm ist zu groß für 4 bits mit Vorzeichen).
In C hängt es von der Implementation ab, ob des Bitfeld vorzeichenbehaftet ist oder nicht (der Typ von Figur ist dort int). In C++ ist hingegen festgelegt, dass (mit dem ursprünglichen Code) 4 bits ausreichen, der verwendete Compiler also wohl nicht konfrom.