Je ne sais pas d'où vient l'idée que char
ou int
est calculé comme "8 octets". Non, chaque type est calculé en fonction de sa taille: char
comme 1, int
comme 4 sur une plate-forme 32 bits (pas 8, mais 4). L'exigence d'alignement pour chaque type est normalement la même que sa taille (bien que cela ne soit pas obligatoire).
Pour cette raison, lorsque la structure contient les membres du même type, la taille totale de cette structure sera normalement la somme exacte des tailles de ses membres: une structure de 3 char
s auront la taille 3 et la structure de deux int
s aura la taille 8.
Apparemment, tapez short
sur votre plate-forme a la taille 2, donc, normalement, une structure de 3 courts métrages a la taille 6, ce qui est exactement ce que vous observez.
Toutefois, lorsque votre structure contient des membres de différents types, la différence entre les exigences d'alignement de différents types entre en jeu. Si l'exigence d'alignement du champ suivant est plus stricte que l'exigence d'alignement du champ précédent, le compilateur peut devoir ajouter des octets de remplissage entre ces champs (pour aligner correctement le membre suivant), ce qui affectera la taille finale de la structure. En outre, le compilateur peut avoir à ajouter des octets de remplissage supplémentaires après le dernier membre de la structure pour satisfaire les exigences d'alignement dans un tableau.
Par exemple, une structure qui se présente comme suit
struct S {
char c;
int i;
};
occupera probablement 8 octets sur votre plate-forme en raison de la nécessité de 3 octets de remplissage après que le membre char
. Remarque, char
compte comme 1, int
comme 4 et les 3 octets de rembourrage supplémentaire entre les rendre 8.
Notez également que cela pourrait facilement introduire la dépendance de la taille finale de la structure de l'ordre dans lequel les membres sont déclaré. Par exemple, cette structure
struct S1 {
char c1;
int i;
char c2;
};
sur votre plate-forme aura probablement la taille 12, alors que celui-ci
struct S2 {
int i;
char c1;
char c2;
};
occupera seulement 8 octets. Ce dernier exemple est destiné à illustrer que la taille finale de la structure ne peut pas être exprimée en termes de nombre d'octets pour lesquels chaque membre "compte". Les relations entre les membres sont également importantes.
Ce n'est pas que je veuille un alignement particulier, c'est juste que je pensais que l'alignement de 4 octets était toujours respecté sur les architectures 32 bits –
Si seulement! Il serait certainement beaucoup plus facile d'écrire des allocateurs de mémoire ...Malheureusement, l'alignement peut différer d'un type à l'autre et il n'y a aucune manière portable de demander au compilateur l'alignement particulier d'un type donné, bien qu'il y ait des astuces. –
'#define aligner (type) ((char *) & ((struct {char dummy; type x;} *) 0) -> x - (char *) 0)' –