Dans le langage C, les structures (struct) peuvent inclure d'autres structures et différents types de données. Cependant, la disposition des champs à l'intérieur d'une structure peut influencer sa taille et son alignement. Le compilateur ajoute des octets supplémentaires (padding) pour respecter l'alignement (alignment) du champ le plus large. Cela est important pour les performances et le bon fonctionnement du processeur.
Si une structure contient des structures imbriquées, l'alignement est appliqué de manière récursive :
#pragma pack dans MSVC ou l'attribut __attribute__((packed)) dans GCC/Clang).Exemple :
#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 (sur 64 bits), sizeof(struct Outer) = 16 ou 24
L'utilisation de pack et packed réduit la taille en ignorant l'alignement, mais cela peut diminuer les performances ou provoquer des erreurs sur certaines plateformes (ARM, DSP, etc.).
Question : Peut-on garantir une taille identique d'une même structure sur toutes les plateformes ?
Réponse : Non ! La norme C ne garantit pas le même alignement, l'ordre des octets (endian), et peut "ajouter" du padding entre les champs et à la fin de la structure. Pour la compatibilité binaire des structures, utilisez une gestion manuelle de l'alignement et testez toujours explicitement sizeof sur chaque plateforme cible.
Exemple :
struct Data { char c; int x; }; // sizeof(Data) est généralement 8 sur 64 bits, 5 ou 8 sur 32 bits
Histoire
Lors de l'échange d'une structure entre un microcontrôleur (ARM) et un PC via un protocole binaire, les données provenant de l'ARM ne correspondaient pas aux attentes sur le PC — en raison de différents padding et ordres d'octets. Cela a conduit à des paramètres mal décodés, entraînant des erreurs physiques dans le contrôle de l'appareil.
Histoire
Dans un protocole réseau pour accélérer l'envoi de données, des structures packed ont été ajoutées, mais il n'a pas été pris en compte que sur une plateforme sans alignement, certains champs ne fonctionnaient pas (le processeur ne supportait pas l'accès non aligné). Résultat : exceptions matérielles lors du travail avec des paquets réseau.
Histoire
Le serveur travaillait avec un fichier externe composé d'enregistrements de structure. Après la mise à jour du compilateur, la taille de la structure a changé (autre alignement). Les anciennes données dans le fichier ont cessé d'être lues correctement, une partie des informations est devenue "corrompue".