Ich verwende __attribute__((packed))
, um das Struct Padding zu vermeiden. Der folgende Code funktioniert einwandfrei, aber wenn ich ein weiteres int
-Member innerhalb der Struktur hinzufüge, füllt der Compiler meine Struktur auf.
Der obige Code funktioniert wie erwartet und die Größe von obj
ist 9 Bytes (mit Auffüllung war es 12 Bytes).
Wenn ich jedoch int d
in meiner Struktur auskommentiere, gibt der Code aus:
Größe von obj ist: 16 Bytes
anstelle der erwarteten 13 (9 + 4) Bytes.
Was ist los?
In Strukturen sind zwei Arten von Padding beteiligt. (1) Padding hinzugefügt, um die Struktur zu einem Vielfachen einer bestimmten Zahl zu machen (In Ihrem Fall die Größe von int
) und (2) Padding hinzugefügt, um bestimmte Datentypen an einer Adresse zu platzieren, die durch eine bestimmte Zahl teilbar ist. Zum Beispiel 4 Bytes für int
. Also in Ihrem Fall, während der Compiler ist glücklich, die erste Art von Padding zu entfernen Ich denke, es immer noch das Mitglied int d
auf eine Adresse durch 4 teilbar. Da es 5 Zeichen vor d
, 3 Bytes Padding hinzugefügt wird, um zu erzwingen d
an eine Adresse, die durch 4 teilbar ist.
Versuchen Sie also, das Mitglied int d
über die Zeichen zu bewegen. Dann müssen Sie natürlich den verwendeten Offset in fetching value of c4 through offset
ändern. Sie können es sogar über c5
setzen. Dann müssten Sie Ihre fetching value of c4 through offset
-Zeile nicht ändern. Beispiel:
ODER
%Vor%Danke an alle, die sich die Zeit genommen haben, in Besonderheiten einzudringen. Ich würde gerne das Verhalten des Compilers, den ich nach verschiedenen Checks verwende, erzählen und möchte mich an die Tatsache halten, dass in beiden Szenarien, d. h. mit und ohne Padding, möchte der Compiler, dass das ganze Element auf die Adresse fällt, die durch seine Größe teilbar ist, in diesem Fall 4 Bytes (Pads dazwischen), die zwar nicht definiert sind "Verwendung von Attribut" funktioniert aber immer noch guten Zweck. Wie wir wissen, und ich nehme an, Compiler mehr Wert auf Geschwindigkeit statt Platz und damit sparen Sie Zeit bei der Durchführung von Anweisungen und speichern Maschinenzyklus. Wenn der Compiler nach dem obigen Protokoll voraussetzt, dass das nächste Element, auf das es trifft, eine Ganzzahl ist, dann ist dies die beste Bedingung, da der Compiler sich dann keine Gedanken über das Auffüllen oder Nicht-Auffüllen machen muss weil die nächste ganze Zahl definitiv auf die Adresse fällt, die durch 4 teilbar ist (Bytes). Es ist sogar noch besser, wenn double eine Größe von 4 Byte hat, wie in einem 32-Bit-Archimed von Linux. Eine Sache, die ich sicherstellen kann, ist, im Falle der keine Auffüllung (unter Verwendung von Attribut) Compiler vermeidet Pads am Ende, sondern im Falle der Padding Compiler Pads Bytes dazwischen sowie am Ende zu machen ganze Strukturgröße dividierbar durch 4. (weil Strukturgröße, die durch 8 teilbar ist (doppelte Größe auf irgendeiner Maschine), auch durch 4 teilbar ist. Als Frage und Funktionsweise ist Compiler vollständig so basiert es war nicht fair für alle, deshalb noch mehr danke.