2013-07-24 5 views
31

Dans c/C++ (je suppose qu'ils sont les mêmes à cet égard), si je donne les résultats suivants:alignement struct C/C++

struct S { 
    T a; 
    . 
    . 
    . 
} s; 

est la suivante garantie pour être vrai?

(void*)&s == (void*)&s.a; 

Ou en d'autres termes, est-il une quelconque garantie qu'il n'y aura pas de remplissage avant le premier membre?

+1

Ils ne sont pas les mêmes à cet égard –

+3

@MooingDuck: Eh bien, cela dépend de ce que le '...' est. Pour la même définition de structure, C++ la traitera de la même manière que les structures C (C répondent toujours à l'exigence C++ * standard-layout *). –

Répondre

44

En C, oui, ils sont la même adresse. Simple et direct.


En C++, non, ils n'ont pas la même adresse. Les classes de base peuvent (et je suppose que c'est le cas) venir avant tous les membres, et les fonctions de membres virtuels ajoutent généralement des données cachées à la structure quelque part. Encore plus confus, un compilateur C++ peut également réorganiser les membres à volonté, sauf si la classe est un type de mise en page standard (bien que je ne sache pas qu'un seul compilateur le fasse)

Enfin, si la structure C++ est composée de standard types de présentation, ne contient pas de classes de base ni de fonctions virtuelles et tous les membres ont la même visibilité, et éventuellement d'autres limitations que j'ai oublié, puis il retombe sur les règles C, et exige que le premier membre soit à la même adresse que le objet lui-même.

§ 9,2/7

Une classe standard de mise en page est une classe qui:
- n'a pas d'éléments de données non statiques de type classe non-standard de mise en page (ou réseau de tels types) ou référence,
- n'a pas de fonctions virtuelles (10.3) et pas de classes de base virtuelles (10.1),
- a le même contrôle d'accès (Clause 11) pour tous les éléments de données non statiques,
- n'a pas non normalisation classes de base de mise en page,
- l'une ou l'autre n'a aucun membre de données non statiques
- n'a pas de classes de base du même type que le premier membre de données non statiques et ne possède aucune classe de base avec des membres de données non statiques. .

§ 9.2/20

un pointeur vers un objet struct standard mise en page, converti de manière appropriée en utilisant un reinterpret_cast, les points à son élément initial (ou si ce membre est un champ binaire, puis à l'unité dans laquelle il réside) et vice versa. [Note: Il peut donc y avoir un bourrage sans nom dans un objet struct de mise en page standard, mais pas au début, comme nécessaire pour obtenir un alignement approprié. -end note]

+0

"standard-layout class" est également connu sous le nom POD ("plain old data type"), et vous pouvez le vérifier en utilisant std :: is_pod. – marcinj

+10

@marcin_j: Non. POD nécessite à la fois * construction standard * et * construction/copie/destruction * triviale. Une classe peut avoir des constructeurs et des destructeurs non-par défaut et d'autres membres spéciaux et être toujours * standard-layout *. –

+0

merci pour la clarification, je vois qu'il est possible d'utiliser std :: is_standard_layout pour vérifier si une telle comparaison est correcte. – marcinj

16

Oui, c'est le cas.

Il est garanti qu'il n'y a pas de remplissage avant le premier membre struct en C et en C++ (s'il s'agit d'un POD).

C citation:

(C11, 6.7.2.1p15) "Il peut y avoir des remplissages sans nom dans un objet structure, mais pas à son début."

citation C de:

(11 C++, 9.2p20) « Il pourrait donc y avoir des remplissages sans nom dans un objet struct standard mise en page, mais pas à son début, si nécessaire pour atteindre appropriée alignement "

+6

En C++, il n'est garanti que s'il s'agit d'un POD. –

+0

@ n.m. ajouté un devis pour C++ et une mention pour POD. Merci – ouah

+0

@ n.m. Si c'est quoi un POD? La structure 'S' ou le membre' T'? – baruch