31 votes

struct alignment C/C++

En c/c++ (je suppose qu'ils sont les mêmes à cet égard), si j'ai ce qui suit :

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

L'affirmation suivante est-elle garantie ?

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

Ou en d'autres termes, y a-t-il une sorte de garantie qu'il n'y aura pas de rembourrage avant le premier membre ?

44voto

Mooing Duck Points 27497

En C, oui, c'est la même adresse. Simple, et direct.


En C++, non, ce n'est pas la même adresse. Les classes de base peuvent (et je soupçonne qu'elles le font) venir avant tous les membres, et les fonctions des membres virtuels ajoutent généralement des données cachées à la structure quelque part. Encore plus déroutant, un compilateur C++ peut également réarranger les membres à volonté, à moins que la classe ne soit un type de disposition standard (bien que je ne sache pas si un compilateur le fait).

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

§ 9.2/7

Une classe de mise en page standard est une classe qui :
- n'a aucun membre non statique de type classe de mise en page non standard (ou tableau de tels types) ou référence,
- n'a aucune fonction virtuelle (10.3) et aucune classe de base virtuelle (10.1),
- a le même contrôle d'accès (clause 11) pour tous les membres de données non statiques,
- n'a pas de classes de base de mise en page non standard,
- soit n'a aucun membre de données non statiques dans la classe la plus dérivée et au plus une classe de base avec des membres de données non statiques, soit n'a aucune classe de base avec des membres de données non statiques, et
- n'a pas de classes de base du même type que le premier membre de données non statique.

§ 9.2/20

Un pointeur vers un objet struct de format standard, convenablement converti à l'aide d'un reinterpret_cast, pointe vers son membre initial (ou si ce membre est un champ de bits, vers l'unité dans laquelle il réside) et vice versa. [Note : Il peut donc y avoir un remplissage sans nom à l'intérieur d'un objet struct standard-layout, mais pas à son début, comme nécessaire pour obtenir un alignement approprié. -fin de la note ]

16voto

ouah Points 75311

Oui, c'est vrai.

Il est garanti qu'il n'y a pas de remplissage avant le premier membre de la structure en C et en C++ (si c'est un POD).

Citation :

(C11, 6.7.2.1p15) "Il peut y avoir un remplissage sans nom à l'intérieur d'un objet structure, mais pas à son début."

Citation de C++ :

(C++11, 9.2p20) "Il peut donc y avoir un remplissage sans nom à l'intérieur d'un objet struct à disposition standard, mais pas à son début, comme nécessaire pour obtenir un alignement approprié".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X