Union
-
Hallo!
Ich habe eine Klasse zum Speichern eines Farbwertes geschrieben. Ich muss nun sowohl die einzelnen Farbkomponenten (jeweils 1 Byte) als auch den gesamten Farbwert (als DWORD im Format ARGB, wobei jede Komponente 1 Byte belegt) abfragen können.
Derzeit speichere ich einfach 4 unsigned chars. Beim Abrufen als DWORD baue ich das Datenwort mit Shift-Operationen und |-Verknüpfungen zusammen.
Da diese Abfrage sehr häufig vorkommt möchte ich das optimieren. Ich habe da an eine Union gedacht, so dass die Konvertierung entfällt, da die Einzelkomponenten und das DWORD im gleichen Speicher liegen.
Frage: Wie muss Deklaration aussehen (kenne mich mir Unions nicht so gut aus), damit das genannte Format (ARGB) des DWORDs entsteht? D.h. vor allem in welcher Reihenfolge müssen die Einzelkomponenten deklariert werden? Ok, das könnte ich einfach ausprobieren, die wichtigere Frage ist eigentlich: legt jeder Compiler die Variablen in der gleichen Reihenfolge ab (steht das im Standard?)? Nicht dass dann bei anderen Compilern plötzlich das DWORD umgekehrt (BGRA) aufgebaut ist.
Danke schonmal!
mfg
-
Intel-Format x86 = Littel Endian LHLH
Motorola = Big Endian HLHL
H = High-Byte
L = Low-Byte
Hoffe, dies hilft dir weiter.
-
Ja, das weiß ich schon. Aber das gilt ja nur innerhalb eines Datenwortes und ist prozessorabhängig.
Was ich wissen wollte ist folgendes: wenn ich 2 Variablen deklarieren:
int a, b;Welche steht dann an der niederwertigen Adresse? Und was das wichtigere ist: ist das immer so? Sollte imho eher compiler- als prozessorabhängig sein (falls überhaupt).
mfg
-
Zitat "... prozessorabhängig"
Richtig, aber es geht dir doch darum wie die Bytes im Speicher abgelegt werden, der Compiler
richtet sich nach dem CPU-Format und es macht schon einen Unterschied ob dein unsigned char
an Speicherstelle 0 oder 3 abgelegt wird.Zitat ..."das gilt ja nur innerhalb eines Datenwortes"
Wie soll ich das verstehen, ein word hat bei mir size 2 und ein dword size 4
Es gibt zum Formatwandeln in Assembler den bswap-Befehl, der vertauscht die Bytes in einem
32-Bit Register, genauer gesagt wird das 1 mit dem 4 und das 2 mit dem 3 Byte vertauscht,
das alles landet im Speicher.Die Reihnfolge im Speicher würde ich durch unsigned char a[4], b[4]; erzwingen. Da macht der
Compiler alles richtig . Bei int Werten wirken die prozessorabhängigen Sachen, würd ich nicht
benutzen, um einzele char an bestimmten Stellen abzulegen.mfg
-
Ich habe es so gemeint: es geht mir nicht darum wie die einzelnen Bytes eines WORDs oder DWORDs abgelegt werden (schon auch, aber diese Frage war für mich von Anfang an beantwortet).
Was ich jetzt wissen will ist das: Ich habe 2 komplett unabhängige Variablen (egal welcher Datentyp, sagen wir halt es sind chars). Die Frage ist jetzt welche davon die niedrigere Adresse hat. Ausprobieren zeigt: die, die man weiter unten im Code deklariert (d.h. die Adressen werden offensichtlich absteigend vergeben). Ich möchte jetzt nur wissen ob das immer so ist, oder ab das ein anderer Compiler eventuell anders macht.
mfg
-
Meines Wissens, der Compiler ist an die Reihenfolge, die du vorgibst nicht gebunden.
Eine Reihenfolge kann man durch Anlegen eines Arrays erzwingen.
statt
int a, b;int ab[2]; schreiben. ab[0] ist immer vor ab[1];
mfg
-
Danke, das mit dem Array ist eine gute Idee. Ich werde das so machen.
mfg