7
votes

Pourquoi la taille de ma syndicale est-elle plus grande que prévu?

Lorsque j'imprime la taille d'un syndicat comme ceci: xxx

en utilisant ceci: xxx

I Obtenir une réponse de 8 Visual C ++, mais je m'attendais 5. Pourquoi?

Eh bien, pour le même exemple, J'ai fait quelque chose comme ça: xxx

J'ai des résultats comme xxx

pourquoi y a-t-il 6FS à UN.c [3 ]


0 commentaires

5 Réponses :


1
votes

Le compilateur peut ajouter du remplissage partout où il veut des structures, des syndicats et des classes pour accélérer les accès à la mémoire. Vous voyez l'effet de cela. Pour Visual C ++, le rembourrage est généralement un multiple de la taille du type de membre le plus important. Dans ce cas, le plus grand membre est un Int, donc il couvre l'Union avec 3 octets inutilisés pour faire la taille totale 8.


6 commentaires

En supposant des entiers de 4 octets, le plus grand membre est C, soit 5 octets. Le compilateur arrondit cela jusqu'à 8 en ajoutant un rembourrage. Si le système utilise des entiers de 8 octets, alors 8 est utilisé pour la taille de l'Union.


@Brian j'ai changé ma réponse peu de temps avant de commencez à "le plus grand type membre", pour indiquer plus clairement un int.


Je ne pense toujours pas que votre réponse soit claire ou correcte. Vous dites que le plus grand membre est un int, mais ce n'est pas le cas. C'est un tableau de 5 caractères. Depuis 5> 4, il arrondit jusqu'au prochain multiple de la taille de mot natif, ce qui en fait 8.


Eh bien, peut-être que nous disons la même chose, juste légèrement différemment après tout.


@Brian bien prendre cela par exemple: union {CHAR [9]; Double D; }; sur MSVC ++, la taille est de 16. Lorsque je dis "type de membre le plus important", je veux dire le type le plus important qui envisage des tableaux par les éléments qui sont en eux. Parce que char est un type de base mais char [5] est une sorte de "type composé".


Je vois ce que vous dites mais je conviens que ce n'est pas clair et légèrement trompeur de la façon dont il est formulé



3
votes

L'alignement de votre syndicat doit être le plus grand alignement de l'un de ses membres. Ceci est 4. Par conséquent, la taille de l'Union doit être alignée sur cette taille. Cela aurait pu être 5 (comme C est le plus grand membre de l'Union), mais parce que l'alignement de l'Union dans son ensemble est de 4, la taille de l'Union est rembourrée à 8.

Notez que c'est juste pour VC ++. La norme ne l'exige pas spécifiquement. Bien que cela permettrait aux implémentations des types de pads au besoin, quels vc ++ font. GCC pourrait faire quelque chose de différent et il pourrait y avoir des commutateurs de compilation que vous pourriez utiliser pour changer ce comportement.


0 commentaires

11
votes

Le Taille de l'opérateur produit la taille d'une variable ou de type, y compris tout remplissage nécessaire pour séparer les éléments dans un tableau de ce type que tout est toujours correctement aligné. Étant donné que votre syndicat a un membre int , il doit être aligné de 4 octets, de sorte que sa taille "naturelle" est arrondi vers le haut vers le prochain multiple de 4 octets.


Le FFFFFF98 est parce que vous compilez avec signé char . En utilisant % x avec un argument qui n'est pas non signé INT provoque un comportement non défini; Ce que vous voyez est parfois appelé signer-extension . Le résultat de votre aliasing est 0x98 réinterprété comme char , qui est -104 . Cela conserve sa valeur sur la promotion de int (ceci s'appelle les argument de défaut ) et l'int -104 lorsqu'il est aliasé comme Unsigné Int devient 0xFFFFFF98 .


0 commentaires

0
votes

Merci pour vos suggestions. J'ai essayé cela avec beaucoup d'exemples et regarde ça La taille de l'union équivaut à (taille de l'élément max) + rembourrage (en fonction de la taille du type de données le plus élevé utilisé).


0 commentaires

2
votes

Entrez la description de l'image ici Compiler ajoute peu d'octets pour l'alignement


0 commentaires