Am Mon, 2003-05-19 um 16.24 schrieb Andre Heine:
Hi Ralf,
From: "Ralf Corsepius"
Am Mon, 2003-05-19 um 11.41 schrieb Andre Heine:
From: "Ralf Corsepius"
Am Sam, 2003-05-17 um 16.23 schrieb Andre Heine:
[...]
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.
Was genau meinst du mit I/O, Dateien oder I/O an einem Port, oder gar beides? Beides. Irgendeine _binäre_ Ein- oder Ausgabe.
Habe ich z.B. einen Port, der 8 Bit breit ist und jeden Pin mit ein bit zugeordnet, dann ändert das doch nichts *wunder*. Da ist doch immer PIN 8 = bit7 (jenachdem wie ich das Verknüpfe ....) Die entscheidende Frage hier wäre: Liegt bit0/bit7 im LSB oder MSB? Liegt bit0 auch im LSB der union?
Es ist implementationsabhängig.
Meinst Du das als "interne Datenstruktur"? Mit interner Datenstruktur war gemeint, dass Du dein C-Bitfelder nur innerhalb von Applikationen/Libs verwendest und sie nicht direkt ausgibst.
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 ; Typo: Da hätte unsigned char pad1; stehen sollen.
unsigned char c20:1; } u; } mytype ;
Frage: An welchem Bit in i steht c13?
In der Tat nicht einfach, die Union hat einen anderen Typ als das struct und damit unterschiedliche lange Typen. Ich weiss auch nicht, was der Compiler mit dem "leeren" Bit macht, wird das angehängt oder an die korrekte Position gestellt? War ein Typo (Siehe oben).
Bitte die Auflösung :)))) Es ist implementationsabhängig und hängt von einer Vielzahl von Faktoren ab. [Stichworte: Endianness, Struct-Alignment, Packing u.v.a.]
Einfaches Beispiel:
#include
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.
Das würde zwar reichen, aber jetzt fange ich an zu überlegen *grummel* Doch alle Bitfelder raus und durch "Bit Ops" ersetzen? Das wäre ein anderes Extrem. Wenn Du Bitfelder nicht binär ein- und ausgibst, vorwiegend einzelne Bits auswertest, Geschwindigkeit und Portabilität nicht im Vordergrund stehen, Du wert auf übersichtlichen, wartbaren Code legst, spricht nicht viel gegen C-Bitfelder.
Wenn Du HW-nahen Code (Treiber o.ä.), geschwindigkeitskritischen Code (Kernel, libc, Signalverarbeitung o.ä.) schreibst und/oder binärer I/O im Vordergrund steht, würde ich zu Ordinaltypen mit Masken greifen. Ralf