Am Mon, 2003-05-19 um 11.41 schrieb Andre Heine:
Hi Ralf,
From: "Ralf Corsepius"
Am Sam, 2003-05-17 um 16.23 schrieb Andre Heine: [...]
Im C Buch von Suse Press steht, das Bitfelder langsamer sind, weil diese intern "shiften", bit Verknüpfungen(& |) sollen sehr performant sein, aber nicht speicherefffizient wie Bitfelder... So pauschal ausgedrückt, ist diese Aussage falsch. Die Effizienz von C-Bitfeldern ist sehr compiler- und prozessorabhängig. Das Ergebnis kann je nach Anwendung, Compiler und Prozessor sehr unterschiedlich ausfallen.
Das stimmt, Bits können je nach Prozessor/ Compiler anders angeordnet sein.
Darauf bezog ich mich an dieser Stelle gar nicht. Was ich meinte, ist folgendes: Was ist scheller und portabler? a) "Bitfeld-Char": struct { unsigned char c0:1; unsigned char c1:1; } b; .. b.c0 = 1; b.c1 = 1; ... if ( (b.c0 == 1) || (b.c1 == 1) ) /* tu was */ .. .. b.c1 = 1; .. oder b) "Bit-Masken/Char" char c ; ... c = 0x03; if ( c & 0x03 ) /* tu was */ .. c |= 0x02 ; b) ist in der Regel erheblich schneller, da mehrere Bits gleichzeitig verarbeitet werden, dafür aber unübersichtlicher. Wertet man in seinem Code aber nur einzelne Bits aus, geht dieser Vorteil von b) verloren, In diesem Fall kann der Compiler zur Verarbeitung der Bitfelder dann u.U. spezialisierten Code erzeugen, der den einfachen "Bit-Ops" des Bit-Masken-Ansatzes überlegen und schneller sein kann.
Aber wenn ich ein Bitfeld habe, wo ich "union.bittyp.bit0 = 1" setze, muss das ist immer so sein!
Ich meine, es ist egal das der Compiler das nun rechts oder links anordnet. bit0 im struct ist immer '1'. Jein, solange Du diese Struct nur als interne Datenstruktur verwendest spielt es keine Rolle. Sobald aber I/O ins Spiel kommt, sieht die Sache anders aus.
In meinen Beispiel benutze ich in einer "union" eine "unsigned char" mit einem Bitfeld, d.h, wenn nun der Compiler die Bits anders für das "unsigned char" anordnet, ist das natürlich fatal, weil eben die Reihenfolge anders ist.
Das wird ein BUG im Programm, den ich nicht gerne suchen möchte :)) ;) Ja, soetwas ist teuflisch zu suchen.
( Wer denkt sofort an die Bitausrichtung, na gut Ralf schon *Grins* ) Ach, diesen Diesen Punkt erreicht man schnell, wenn man sich mal mit Hardware-naher Programmierung oder mit Kommunikation zwischen verschiedenen OSen und/oder Architekturen beschäfftigt. -- Ich bin in beiden Feldern zu Hause.
Man lernt dann schnell scheinbar elegante Tricks ähnliche diesem hier zu vermeiden: union { unsigned int i; struct { unsigned char pad0:7; unsigned char c7:1; unsigned char c8:1; unsigned char pad:5; unsigned char c13:1; unsigned char ; unsigned char c20:1; } u; } mytype ; Frage: An welchem Bit in i steht c13? SCNR :-)
[...]
Meine Vorliebe liegt bei den Bitfeldern, lässt sich im Quelltext viel besser lesen. Grösster Nachteil von C-Bitfeldern: Die interne Reihenfolge der Bits innerhalb von structs ist nicht definiert. D.h. so bald C-Bitfelder binär ausgegeben werden sollen oder Hardware mit Bitfeldern angesteuert werden sollen, wird der Code unportabel.
Das habe ich, ehrlich gesagt, gar nicht bedacht...
Da brauche ich eigentlich nur die vorhandenen Bitfelder "umdrehen" und schon sollte mein Code immernoch lesbar sein und auch dieses manko beheben.
Ja, zumindest mit gcc auf 32bit-Architekturen funktionieren derartige Tricks meist.
Mit defines kann man das ja Konfigurieren, welche bitfelder genommen werden, je nach Prozessor ... Hmm, sehr problematisch, da der Prozessortyp alleine keinen Rückschluss darüber erlaubt wie Bitfelder angeordnet werden.
In vielen Fällen reicht es allerdings die Endianness/Byteorder zu analysieren, (Manche Prozessoren können mehrere "Endiannesses"; dort ist Endianness normalerweise ein Compiler-Flag). Es gibt aber auch noch exotischere Systeme, in denen das nicht ausreicht (Fragestellung der Wortbreite einer Architektur: 8/16/32/64bit; VAX-Byteorder. Structure-Alignment u.ä.) Der Work-around ist allerdings einfach: Entweder auf I/O von Bitfeldern verzichten oder nur Ordinaltypen und Bit-Ops verwenden (Diese sind portabel und haben keine Byteorder/Alignment-Probleme.) Ralf