Padding Bytes in Byte struct
-
@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?
-
@Bushmaster sagte in Padding Bytes in Byte struct:
es soll prozessoren geben, die nur 16bit-speicherzugriffe können. zugriff auf eine ungerade adresse löst eine hardware exception aus.
Aber auch da kommt man - mit etwas Aufwand - an die Daten.
Wird der Aufwand gescheut, gibt es Padding.
-
@DirkB sagte in Padding Bytes in Byte struct:
Aber auch da kommt man - mit etwas Aufwand - an die Daten.
ja, besonders schreibzugriffe auf uint8_t sind von übel, weil zuerst das 16bit-wort gelesen werden muss, weil man ja die eine hälfte nicht zerstören will.
-
@Swordfish sagte in Padding Bytes in Byte struct:
@hustbaer sagte in Padding Bytes in Byte struct:
dass der Compiler unnötiges Padding einfügen darf.
Wo?
Zwischen struct/class Membern.
Ich weiss nicht wie das im Standard genau formuliert ist, hab nicht nachgelesen. Eine "nicht-Standard" Quelle die ich auf die Schnelle gefunden habe hat es formuliert ala "may insert padding to meet the alignment requirements". Das wäre eine schwammige Formulierung die es weder explizit erlaubt noch explizit verbietet.
-
@Bushmaster sagte in Padding Bytes in Byte struct:
@DirkB sagte in Padding Bytes in Byte struct:
Aber auch da kommt man - mit etwas Aufwand - an die Daten.
ja, besonders schreibzugriffe auf uint8_t sind von übel, weil zuerst das 16bit-wort gelesen werden muss, weil man ja die eine hälfte nicht zerstören will.
Auf solchen Systemen darf es - wenn ich das alles richtig verstehe - sowieso kein
uint8_t
geben. Wegen memory model und so.
Denn Schreib- und Lesezugriffe aufmyUint8Array[0]
in einem Thread dürfen mit Schreib- und Lesezugriffen aufmyUint8Array[1]
in einem anderen Thread nicht kollidieren.
Zumindest ist das in C++ so, bitte korrigiert mich wenn das in C anders ist.Und das lässt sich einfach nur vernünftig machen wenn die CPU auch einzelne Bytes direkt schreiben kann. Wenn dazu mehrere Befehle nötig sind, kenne ich nur zwei Möglichkeiten das umzusetzen, und beide sind nicht "vernünftig":
- Atomics - viel zu teuer
- Hardware Transactional Memory - ebenfalls teuer und auf kaum einer CPU implementiert
Falls ich hier nen Denkfehler habe, bitte ich ebenfalls um Korrektur.
EDIT: OK, Annahme hier natürlich: das Ding unterstützt überhaupt echtes Multithreading. D.h. das Argument gilt natürlich nur für Systeme mit Multithreading. Hm. Schade