In der Programmiersprache C können Strukturen (struct) andere Strukturen und verschiedene Datentypen enthalten. Die Anordnung der Felder innerhalb der Struktur kann jedoch deren Größe und Ausrichtung beeinflussen. Der Compiler fügt zusätzliche Bytes (Padding) hinzu, um die Ausrichtung (Alignment) des größten Feldes zu gewährleisten. Dies ist wichtig für die Leistung und das korrekte Funktionieren des Prozessors.
Wenn eine Struktur verschachtelte Strukturen enthält, wird die Ausrichtung rekursiv angewendet:
#pragma pack in MSVC oder das Attribut __attribute__((packed)) in GCC/Clang).Beispiel:
#include <stdio.h> struct Inner { char c; int x; }; struct Outer { char a; struct Inner b; short s; }; int main() { printf("sizeof(struct Inner) = %zu\n", sizeof(struct Inner)); printf("sizeof(struct Outer) = %zu\n", sizeof(struct Outer)); return 0; } // sizeof(struct Inner) = 8 (auf 64-Bit), sizeof(struct Outer) = 16 oder 24
Die Verwendung von pack und packed verringert die Größe, indem die Ausrichtung ignoriert wird, kann jedoch die Leistung beeinträchtigen oder Fehler auf einigen Plattformen (ARM, DSP usw.) verursachen.
Frage: Kann man garantieren, dass die Größe der gleichen Struktur auf allen Plattformen gleich ist?
Antwort: Nein! Der C-Standard garantiert nicht die gleiche Ausrichtung, die Byte-Reihenfolge (Endianness) und kann Padding zwischen den Feldern und am Ende der Struktur "hinzufügen". Für die binäre Kompatibilität von Strukturen verwenden Sie manuelle Steuerung der Ausrichtung und testen Sie immer explizit sizeof auf jeder Zielplattform.
Beispiel:
struct Data { char c; int x; }; // sizeof(Data) ist normalerweise 8 auf 64-Bit, 5 oder 8 auf 32-Bit
Geschichte
Beim Austausch einer Struktur zwischen einem Mikrocontroller (ARM) und einem PC über ein binäres Protokoll stimmten die Daten von ARM nicht mit den Erwartungen auf dem PC überein – aufgrund von unterschiedlichem Padding und Byte-Reihenfolge. Dies führte zu falschen dekodierten Parametern, was zu physischen Steuerfehlern des Geräts führte.
Geschichte
Im Netzwerkprotokoll wurden zur Beschleunigung des Datentransfers gepackte Strukturen hinzugefügt, ohne zu berücksichtigen, dass auf Plattformen ohne Ausrichtung einzelne Felder nicht funktionierten (der Prozessor unterstützte keinen Miss-aligned Zugriff). Ergebnis: Hardware-Ausnahmen beim Arbeiten mit Netzwerkpaketen.
Geschichte
Der Server arbeitete mit einer externen Datei, die aus Strukturaufzeichnungen bestand. Nach einem Compiler-Update änderte sich die Größe der Struktur (anderes Alignment). Alte Daten in der Datei konnten nicht mehr korrekt gelesen werden, und ein Teil der Informationen wurde "beschädigt."