Bitfeld Grösse verkleinern
-
Hallo,
ich habe folgendes Problem:
Ich möchte 5 12 Bit Variablen und 4 Flags (je 1 Bit) speichern. Das sind insgesamt 64 Bit (=8 Byte), mehr kann ich dafür nicht verwenden. Ich kann das ganze natürlich mit Bitshifts "von Hand" zusammenbasteln, aber das ist unübersichtlich (und schlechter wartbar). Deshalb wollte ich ein Bitfeld nehmen:// UINT16 ist unsigned short struct { UINT16 adc1 : 12; UINT16 adc2 : 12; UINT16 adc3 : 12; UINT16 adc4 : 12; UINT16 adc5 : 12; UINT16 flag1 : 1; // 3 weitere Flags } myStruct;
Das Problem ist, dass die Grösse dieser Struktur nach dem kompilieren 10 Bytes ist und nicht 8. Es ist mir klar wieso, aber nicht wie und ob ich das beheben kann.
Ich programmiere einen uC (das ist auch der Grund, wieso ich genau 8 Byte für die Struktur zur Verfügung habe), da gibt es keine 64 Bit Datentypen (32 Bit hingegen schon). Gibt es irgendeinen Trick wie ich die Struct auf 8 Byte bringe oder habt ihr einen anderen Ansatz um das Problem zu lösen?
Sonst werde ich das ganze manuell zusammensetzen, aber ich hoffe es gibt eine elegantere Methode ;).
-
Gehts denn mit
// UINT16 ist unsigned short struct { UINT16 adc1 : 12; UINT16 adc2 : 12; UINT16 adc3 : 12; UINT16 adc4 : 12; UINT16 adc5 : 12; UINT16 flag1 : 1; // 3 weitere Flags } myStruct __attribute__ ((packed));
?
-
lustig schrieb:
Das Problem ist, dass die Grösse dieser Struktur nach dem kompilieren 10 Bytes ist und nicht 8. Es ist mir klar wieso, aber nicht wie und ob ich das beheben kann.
Ist mir ohnehin räteselhaft, wie der Compiler auf 10 Byte kommt, normalerweise wird auf's Byte/char gepadded.
Prinzipiell darfst Du aber nicht annehmen, daß bitweise belegt wird, es gibt Kisten, wo ein Bitfield- Bit mindestens einen 16Bit- Int belegt, das ist "implementation specific".Lies mal, was Dein Compiler zu #pragma pack erzählen kann und behalte im Hinterkopf, daß Du nicht portablen Code erzeugst.
-
struct myStruct { unsigned __int64 adc1 : 12; unsigned __int64 adc2 : 12; unsigned __int64 adc3 : 12; unsigned __int64 adc4 : 12; unsigned __int64 adc5 : 12; unsigned __int64 flag1 : 1; // 3 weitere Flags };
So geht das. Der Compiler füllt immer die bits des vorherigen typs auf, sind nicht genug vorhanden, dann wird ein neuer int "aufgemacht" und die übrigen bits verfallen.
EDIT: Hab grad gelesen es gibt keine 64 bit typen? Bei mir schon, desshalb frag ich mich wieso du darauf kommst?
EDIT2: Ahhh, jetzt weis ich was ein uC ist :D, bei µC wär ich vieleicht schneller drauf gekommen, wieder was gelernt
-
Weil er eben für einen Mikrocontroller programmiert. Die haben teilweise nur 64 Byte RAM...
Und da muss man eben Speicher sparen wo man kann
Wenigstens hat er 32er, nichtmal das ist immer sicher dass der Compiler das unterstützt.Ich würde auch auf alignment tippen, also dass der Compiler das (blöderweise hier) versucht günstig zu verteilen.
-
lustig schrieb:
Ich möchte 5 12 Bit Variablen und 4 Flags (je 1 Bit) speichern. Das sind insgesamt 64 Bit (=8 Byte), mehr kann ich dafür nicht verwenden. Ich kann das ganze natürlich mit Bitshifts "von Hand" zusammenbasteln, aber das ist unübersichtlich (und schlechter wartbar). Deshalb wollte ich ein Bitfeld nehmen:
Wenn Du die Zugriffe in (inline)Funktionen auslagerst, bleibt es wartbar und portabel. Ich persönlich versuche Bitfelder so gut es geht zu vermeiden.
-
Vielen Dank für die Antworten. Das mit __attribute__((packed)) und #pragma pack wird von meinem Compiler leider nicht unterstützt, ist aber gut zu wissen, falls ich wieder mal so ein Problem habe.
Habe es jetzt ohne Bitfelder gelöst.Das nächste Mal schreibe ich Mikrocontroller :), dann entsteht keine Verwirrung.
-
Z schrieb:
lustig schrieb:
Ich möchte 5 12 Bit Variablen und 4 Flags (je 1 Bit) speichern. Das sind insgesamt 64 Bit (=8 Byte), mehr kann ich dafür nicht verwenden. Ich kann das ganze natürlich mit Bitshifts "von Hand" zusammenbasteln, aber das ist unübersichtlich (und schlechter wartbar). Deshalb wollte ich ein Bitfeld nehmen:
Wenn Du die Zugriffe in (inline)Funktionen auslagerst, bleibt es wartbar und portabel. Ich persönlich versuche Bitfelder so gut es geht zu vermeiden.
es bieten sich auch #defines an
und dann natürlich ein schönes bit twiddling tutorial