Padding Bytes in Byte struct
-
Hallo zusammen. Folge Frage:
Kann ich mich darauf verlassen, dass eine struct, die nur aus uint8_t Elementen besteht nicht durch Padding-Bytes aufgebläht wird?
Es ist mir bekannt, dass der Compiler zur Zugriffsoptimierung auf das Alignment der einzelnen Elemente achtet und ggf. Padding-Bytes einfügt. Wenn aber alle Elemente vom gleichen Typ (eben z.B. uint8_t...) sind, sollte das Alignment auch ohne Padding-Bytes eingehalten werden oder?
-
Das geht nur mit compilerspezifischen Erweiterungen.
-
@MicroC
du kannst ein array aus uint8_t-elementen nehmen. da wird mit sicherheit nichts aufgebläht. um den 'einzelnen variablen' namen zu geben, kannst du per #define verschiedene indizes definieren.uint8_t array[32]; // und dann ... #define VAR1 array[0] #define VAR_Zwei array[1] // und so weiter ...
-
Warum willst du das wissen?
-
@MicroC sagte in Padding Bytes in Byte struct:
Wenn aber alle Elemente vom gleichen Typ (eben z.B. uint8_t...) sind, sollte das Alignment auch ohne Padding-Bytes eingehalten werden oder?
Nein, es kann wegen des Zugriffs auf Elemente im Struct besser sein, dass Padding Bytes eingefügt werden. Es gibt einen offiziellen Weg auf Elemente von Structs zuzugreifen, und wenn man davon abweicht verlässt man sich auf Plattformspezifika.
-
@TGGC sagte in Padding Bytes in Byte struct:
Das geht nur mit compilerspezifischen Erweiterungen.
@MicroC: Gemeint ist damit z.B. die
#pragma pack
-Anweisung.
-
@MicroC sagte in Padding Bytes in Byte struct:
Kann ich mich darauf verlassen, dass eine struct, die nur aus uint8_t Elementen besteht nicht durch Padding-Bytes aufgebläht wird?
Nein.
-
@Wutz Naja also zumindest praktisch kann man sich schon darauf verlassen. Falls du anderer Meinung bist, wäre interessant wieso.
-
@hustbaer
Weil der Standard das nicht garantiert.
-
@hustbaer sagte in Padding Bytes in Byte struct:
Falls du anderer Meinung bist, wäre interessant wieso.
Z.B. kann nicht jeder Prozessor einfach auf jedes Byte eines Datenwortes zugreifen.
Da kann es günstiger (Laufzeit) sein, die Bytes auf Wortadressen zu legen.
(als Datenwort sind hier Vielfache von einem Byte gemeint)Aber das wäre ein reales Beispiel, damit schlägt sich der Standard nicht rum.
-
@hustbaer sagte in Padding Bytes in Byte struct:
@Wutz Naja also zumindest praktisch kann man sich schon darauf verlassen. Falls du anderer Meinung bist, wäre interessant wieso.
Nein, man kann eben nicht. Das sind so Klassiker wenn Programme von einer Plattform auf eine andere portiert werden, an denen es knallt.
-
@DirkB sagte in Padding Bytes in Byte struct:
Z.B. kann nicht jeder Prozessor einfach auf jedes Byte eines Datenwortes zugreifen.
es soll prozessoren geben, die nur 16bit-speicherzugriffe können. zugriff auf eine ungerade adresse löst eine hardware exception aus.
-
Der einzig sinnvolle Hintergrund der Frage kann ja wohl nur sein, dass der Threadersteller eine wie auch immer geartete Umwandlung vor hat, bei der Layoutkompatibilität von Nöten ist¹. Wenn man solche Pläne hat, muss man sich sowieso mit den Eigenschaften der unterliegenden Plattform auskennen und schreibt keinen portablen Code mehr. Und dann ist das gezeigte Vorhaben eine durchaus gute Vorgehensweise, da die nötige Eigenschaft im allgemeinen Fall fast immer gegeben ist, im speziellen Fall auch leicht überprüfbar ist, und der nötige Code recht einfach zu implementieren ist.
¹: Die wahre Frage ist natürlich: Warum? Was manni66 ja auch prompt gefragt hat, aber leider unbeantwortet geblieben ist.
-
@Bushmaster sagte in Padding Bytes in Byte struct:
@DirkB sagte in Padding Bytes in Byte struct:
Z.B. kann nicht jeder Prozessor einfach auf jedes Byte eines Datenwortes zugreifen.
es soll prozessoren geben, die nur 16bit-speicherzugriffe können. zugriff auf eine ungerade adresse löst eine hardware exception aus.
Ist doch egal, denn das gilt dann ja auch für das Array.
-
Der Standard garantiert diesbezüglich nur (implizit), dass es nie führende Paddingbytes gibt.
-
Das ist mir alles klar. Allerdings, AFAIK:
- Padding ist nicht zwischen Array-Elementen erlaubt
uint8_t
muss, wenn es existiert, genau 8 bit gross sein, ebenfalls ohne Padding oder "unbenutzte" Bitschar
muss mindestens 8 Bit gross seinsizeof(char)
ist garantiert 1
Daraus folgt dann implizit z.B. dass
sizeof(uint8_t)
undalignof(uint8_t)
beide ebenfalls 1 sind.Wo ich mir nicht sicher bin ist ob der Compiler Padding "einfach so" einfügen darf, also auch wenn es nicht nötig wäre um das Alignment-Requirement zu erfüllen.
Wenn er das darf, dann ist es vom Standard aus nicht garantiert, ja.
Ist es in der Praxis relevant? Weiss ich nicht. Wenn man sich darauf verlässt sollte man vermutlich mindestens irgend einen Test haben der sicherstellt dass es auch funktioniert. Oder halt ein
uint8_t
Array verwenden wie ja schon vorgeschlagen wurde.
-
ich nehme an, wenn man eine struktur aus lauter chars hat, dann müsste sizeof die anzahl der elemente ergeben. kommt was größeres raus, hat der compiler was angehängt.
-
@hustbaer Die Anforderung no padding gilt für den Typ
uint8_t
an sich. Hat nichts damit zu tun was zwischen struct-members freigelassen werden darf.
-
@Swordfish sagte in Padding Bytes in Byte struct:
@hustbaer Die Anforderung no padding gilt für den Typ
uint8_t
an sich. Hat nichts damit zu tun was zwischen struct-members freigelassen werden darf.Ja, das verstehe ich schon.
Aber es gibt auch die Anforderung dass Arrays "dicht" sein müssen.
Und aus beiden Anforderungen zusammengenommen ergibt sich dann dassuint8_t
Arrays vollständig "dicht" sein müssen.Oder was meinst du? Ich verstehe nämlich gerade nicht ganz warum du mich darauf hinweist.
ps: Dass man die Garantie für Arrays nicht unbedingt auf structs ausweiten darf ist mir auch klar. Hatte ich denke ich auch schon vorhin geschrieben. Wo ich mir aber nicht sicher bin ist ob der Standard so formuliert ist dass der Compiler unnötiges Padding einfügen darf.
-
@hustbaer sagte in Padding Bytes in Byte struct:
dass der Compiler unnötiges Padding einfügen darf.
Wo?