C: Buffer Alignment
-
Scheppertreiber schrieb:
char buf[4 * irgendwas];
Na und? char != byte, leider nur meistens.
GmbH schrieb:
Und C++ habe ich bisher immer die #pragma pack Erweiterung für Structs & Co. benutzt. Wie mache ich das unter C?
Genauso. pragmas sind allerdings compilerspezifisch, bitte im Bedarfsfall nachlesen.
-
Bei Strukturen machen das die Compiler automatisch (abschaltbar).
Grund: 4x8 Bit = 32, passend für einen 32-Bit-Prozzi.
-
Scheppertreiber schrieb:
Bei Strukturen machen das die Compiler automatisch (abschaltbar).
Grund: 4x8 Bit = 32, passend für einen 32-Bit-Prozzi.Jaa, aaber ... woher willst Du wissen, daß der OP das hat? Bei einigen DSPs sind das 4 * 16 Bit, trotz #pragma pack- Spielereien.
Besser Compi- Doku nachlesen.
-
Scheppertreiber schrieb:
Bei Strukturen machen das die Compiler automatisch (abschaltbar).
Grund: 4x8 Bit = 32, passend für einen 32-Bit-Prozzi.struct foo { char x[4]; }; struct bar { char a[1]; struct foo b; };
wenn das stimmte, müsste die Größe von bar wenigstens 8 statt nur 5 betragen, und somit wird unnötig Platz verschenkt.
#pragma pack, wenn verfügbar, resultiert in unportablem und nicht standardkonformem Code, bei Architekturen mit strengeren Anforderungen als x86 bzgl. Ausrichtugn, gibt es jede Menge Probleme.
Der normale Weg, eine bestimmte Ausrichtung zu erzwingen (abgesehen von Compilerdirektiven/zusätzlichen Attributen) besteht in in der Benutzung eines zusätzlichen Typs mit der gewünschten natürlichen Ausrichtung in einem union. Da Aggregate jeweils die strikteste Ausrichtung ihrer Member haben, führt das zum gewünschten Ergebnis.
-
camper schrieb:
wenn das stimmte, müsste die Größe von bar wenigstens 8 statt nur 5 betragen, und somit wird unnötig Platz verschenkt.
du setzt ja auch nur char-arrays hintereinander. mach mal so:
struct foo { int x[1]; }; // 4 bytes struct bar { char a[1]; // 1 byte // <-- 3 füllbytes struct foo b; // 4 bytes }; // == 8 bytes
-
pointercrash() schrieb:
Scheppertreiber schrieb:
char buf[4 * irgendwas];
Na und? char != byte, leider nur meistens.
GmbH schrieb:
Und C++ habe ich bisher immer die #pragma pack Erweiterung für Structs & Co. benutzt. Wie mache ich das unter C?
Genauso. pragmas sind allerdings compilerspezifisch, bitte im Bedarfsfall nachlesen.
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.
-
asdadad schrieb:
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.was nicht unbedingt einem 'oktett' entsprechen muss.
--> http://en.wikipedia.org/wiki/Octet_(computing)
-
;fricky schrieb:
asdadad schrieb:
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.was nicht unbedingt einem 'oktett' entsprechen muss.
--> http://en.wikipedia.org/wiki/Octet_(computing)
Das hab ich auch nie behauptet, da das hier auch nicht explizit verlangt wurde.
-
asdadad schrieb:
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.Und ich würde sagen, daß Du Dich damit täuschst. Es gibt ein paar Prozessoren, die 16 Bit als kleinste Einheit adressieren können; also ich kenn' jetzt nur ein paar DSPs von TI, aber ganz so selten ist das nicht.
-
pointercrash() schrieb:
asdadad schrieb:
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.Und ich würde sagen, daß Du Dich damit täuschst. Es gibt ein paar Prozessoren, die 16 Bit als kleinste Einheit adressieren können; also ich kenn' jetzt nur ein paar DSPs von TI, aber ganz so selten ist das nicht.
"A contiguous sequence of a fixed number of bits. On modern computers, an eight-bit byte is by far the most common. Certain older models have used six-, seven-, or nine-bit bytes -- for instance on the 36-bit architecture of the PDP-10. A byte is always atomic on the system, meaning that it is the smallest addressable unit. An eight-bit byte can hold 256 possible values (28 = 256) -- enough to store an unsigned integer ranging from 0 to 255, a signed integer from -128 to 127, or an extended ASCII character. "
Quelle: http://www.fact-index.com/b/by/byte.html
asdadad schrieb:
;fricky schrieb:
asdadad schrieb:
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.was nicht unbedingt einem 'oktett' entsprechen muss.
--> http://en.wikipedia.org/wiki/Octet_(computing)
Das hab ich auch nie behauptet, da das hier auch nicht explizit verlangt wurde.
Deine Aussage ist für meine Darstellung vollkommen irrelevant, es handelt sich um ein Byte, aus wieviel Bit es besteht ist nicht von Bedeutung, da dazu vom OP keine Vorgaben gemacht wurden.
-
asdadad schrieb:
;fricky schrieb:
asdadad schrieb:
Ich würde sagen,
char
ist so ziemlich der einzige Datentyp der auf allen Plattformen genau 1 Byte hat.was nicht unbedingt einem 'oktett' entsprechen muss.
--> http://en.wikipedia.org/wiki/Octet_(computing)
Das hab ich auch nie behauptet, da das hier auch nicht explizit verlangt wurde.
ist aber nicht unwichtig, weil der begriff 'byte' nicht allgemeingültig ist.
-
Also byte != char != 8Bit.
Hammas damit?
-
pointercrash() schrieb:
Also byte != char != 8Bit.
Hammas damit?Ein Char ist aber sehr wohl ein Byte.
=> (Char = Byte) != 8Bit
-
;fricky schrieb:
camper schrieb:
wenn das stimmte, müsste die Größe von bar wenigstens 8 statt nur 5 betragen, und somit wird unnötig Platz verschenkt.
du setzt ja auch nur char-arrays hintereinander. mach mal so:
struct foo { int x[1]; }; // 4 bytes struct bar { char a[1]; // 1 byte // <-- 3 füllbytes struct foo b; // 4 bytes }; // == 8 bytes
-
BBBB schrieb:
Ein Char ist aber sehr wohl ein Byte.
=> (Char = Byte) != 8BitNee, echt? char und byte drücken synonym die kleinste adressierbare Einheit aus? Muß mal ein paar Profs erschießen gehen ...
-
Ich glaube, das entscheiden die Plattform-Designer auch mit gesundem Menschenverstand. Es wäre recht unpraktisch, einen einbittigen Byte zu haben, nur weil man z.B. bitweise Adressierung hat. Und Plattformen, die nur aligned-Adressen dereferenzieren können (ARM ist AFAIK immer noch so), müssten dann auf der C-Ebene ungewöhnlich große Bytes haben, was Portierungen erschweren und daher Gewinne schmälern würde.
-
BBBB schrieb:
Ein Char ist aber sehr wohl ein Byte.
=> (Char = Byte) != 8Bitnaja, ein 'char' in C muss mindestens 8 bit haben und ist äquivalent zu einem C-byte. ein 'byte' kann auch kleiner sein, nur eben nicht in C.
pointercrash() schrieb:
char und byte drücken synonym die kleinste adressierbare Einheit aus?
nee, auf 'ner cpu mit z.b. 5 datenleitungen muss das C-byte(char) trotzdem wenigstens aus 8 bits bestehen.
Superlexx schrieb:
Es wäre recht unpraktisch, einen einbittigen Byte zu haben, nur weil man z.B. bitweise Adressierung hat.
wie gesagt, das ist in standard-C nicht erlaubt. schlimmer noch: dadurch, dass 'int' mindestens 16 bits breit sein muss, ist es z.b. auf 8-bit CPUs effizienter, 'char' statt 'int' zu verwenden (für schleifenzähler usw.).
-
Nochmal zurück zum Thema: Ich hatte auch das Problem mit dem Alignment. Ich habe ein Window template gebastelt um eine kleine Dialogbox anzuzeigen. Jedenfalls gibt es dort 4 Structs gefolgt von jeweils einem Titel, ein Menu und sonstige Daten mit variabler Länge die all DWORD oder WORD-aligned sein müssen, alles hintereinander im Speicher. Eigentlich macht man das mit .rc-Dateien aber egal. Ich habe dann sowas gebastelt:
char* memory = malloc(sizeof(struct template)*3 + title1length + title2length + ... + alignmentbytes); while ((int)memory & 3) memory++; //DWORD align //code if ((int)memory & 1) memory++; //WORD align //code
Ist reichlich hässlich aber was besseres ist mir nicht eingefallen. Und im schlimmsten Fall 5 bytes zu verschwenden halte ich nicht für sonderlich tragisch.