est la manière dont les structures C ++ sont définies définies par la norme, ou au moins communes entre les compilateurs? P>
J'ai une structure où l'un de ses membres doit être aligné sur 16 frontières d'octets, ce qui serait plus facile si je peux garantir la commande des champs. P>
Aussi, pour les classes non virtuelles, l'adresse du premier élément est également susceptible d'être l'adresse de la structure? P>
Je suis le plus intéressé par GCC et MSVS. P>
6 Réponses :
C ++ hérite de C Le besoin / désir de travailler efficacement sur de nombreuses plates-formes et laisse donc certaines choses jusqu'au compilateur. En plus de nécessiter des éléments à apparaître dans l'ordre spécifié, c'est l'un d'entre eux. P>
Mais de nombreux compilateurs soutiennent #pragma code> s et options pour vous permettre d'établir le contrôle de l'emballage. Consultez la documentation de votre compilateur. P>
Mais qu'en est-il des exigences ABI? Compilateurs sûrement qui utilisent le même abi devraient avoir la même présentation d'objet. Ce n'est pas une partie de la norme, mais les compilateurs sont généralement conformes à une norme ABI.
@Alex: J'imagine que cela dépend de la façon dont l'abi est exigeant. Même alors, vous devez avoir la possibilité de casser les règles d'interopérabilité avec Autres systèmes i>.
Le chemin C ++ struct sont disposés défini par la norme, ou au moins commune à travers les compilateurs? p> blockQuote>
Il n'y a aucune garantie dans la norme. Je ne dépendra pas des compilateurs ayant le même alignement p>
J'ai un struct où l'un de ses membres doit être alignée sur les 16 octets les frontières, et ce serait plus facile si je peux garantir l'ordre des champs. p> blockQuote>
Compilateurs ne changera pas l'ordre des champs. p>
Voici quelques liens sur la façon de les mettre à la fois GCC et MSVC:
Pour GCC: http: / /developer.apple.com/mac/library/documentation/DeveloperTools/gcc-4.0.1/gcc/Structure_002dPacking-Pragmas.html
MSVC: http://msdn.microsoft.com/en -nous / bibliothèque / ms253935 (VS.80) .aspx et http://msdn.microsoft.com/en-us/library/2e70t5y1 (VS.80) .aspx p>Je les garderais que les structures et utiliser un extern « C » pour faire en sorte que cela fonctionne correctement. Peut-être pas nécessaire, mais qui aurait certainement le travail. P>
Les structures sont aménagées séquentiellement en mémoire. Cependant, la façon dont ils sont alignés dans la mémoire varie en fonction du système d'exploitation. P>
Pour les choses plus grandes que 4 octets, il y a une différence entre Windows et Linux. Linux les aligne comme s'ils sont 4 octets, donc par exemple un double (8 octets) pouvait démarrer à P + 4, P + 8, P + 12, etc. où p est le début de la structure. Sous Windows, un double (8 octets) doit démarrer à une adresse qui est un multiple de 8 SO + 8, P + 16, P + 24, etc. P>
Ce n'est pas déterminé par le système d'exploitation, mais surtout par l'architecture de la CPU et le compilateur.
Qu'est-ce qui vous fait penser que, par curiosité? Le manuel de My College Computing Systems Class dit autrement (Systèmes informatiques: Perspective d'un programmeur, de Bryant & O'Hallaron). Pour autant que je sache, même lorsque vous compilez à l'aide de g ++ en cygwin, il se comporte différemment de G ++ sous Linux.
C'est un peu des deux. Le matériel met une exigence minimale sur tout, mais vous pouvez toujours choisir d'être plus strict. Si MS a choisi de le faire, alors GCC sous Windows n'aurait d'autre choix que de suivre la poursuite.
C La seule différence entre les compilateurs est l'alignement, mais heureusement, MSVC et GCC support struct code> s (et c ++ pods, pour la compatibilité) sont requis par la norme pour avoir une disposition séquentielle . P>
#pragma pack code>. P>
@ DAN04: Consultez ma réponse - tandis que le comité est certainement destiné à i> pour que les gousses disposent de cette exigence, une affaire étrange d'angle a été négligée. L'exigence ne s'applique pas à tous les types de pod.
@ Jerry: Il serait utile que vous puissiez fournir une sorte de référence à cette "affaire bizarre" au profit du reste de nous.
C et C ++ garantissent tous les deux que les champs seront définis dans la mémoire dans le même ordre que vous les définissez. Pour C ++, il n'est garanti que pour un type de pod 1 sup> (tout ce qui serait légitime en tant que structure C [EDIT: C89 / 90 - Non, par exemple, une VLA de C99] sera également qualifié de gousse. ). Le compilateur est libre d'insérer un rembourrage entre les éléments et / ou à la fin de la structure. La plupart des compilateurs vous donnent un moyen de contrôler cela (par exemple, 1 sup> Il y a un cas d'angle où ils ne pensaient pas, où il n'est pas garanti pour un type de pod - un spécificateur d'accès enfreint la garantie de commande: p> ceci est Un type de pod, mais le «code> public: code> entre EDIT: Les parties pertinentes de la norme (au moins la plupart d'entre elles) sont Âces9 / 4: P> Un POD-STRUTT est une classe d'agrégat qui n'a pas de non-volatile
Membres de données de type pointeur à membre, non-POD-STRUTT, non
Pod-union (ou ensemble de tels types) ou de référence, et n'a pas
Opérateur d'affectation de copie définie par l'utilisateur et aucun utilisateur défini par l'utilisateur
destructeur. p>
blockQuote> et §8.5.1 / 1: p> Un agrégat est un tableau ou une classe (clause 9) sans utilisateur.
Constructeurs déclarés (12.1), pas de non-protégé ni protégé
Membres de données statiques (clause 11), pas de classes de base (clause 10)
et aucune fonction virtuelle (10.3). P>
BlockQuote> et §9.2 / 12: P> ... l'ordre d'attribution des membres non statiques de données
séparé par un spécificateur d'accès n'est pas spécifié (11.1). p>
BlockQuote> Bien que cela soit restreint quelque peu par 14,2 / 17: P> Un pointeur sur un objet de structure de pod, converti convenablement en utilisant
Un réinterpret_cast, pointe vers son membre initial ... P>
blockQuote> Par conséquent, (même si précédé d'un Je devrais également souligner qu'il y a une place à l'argumentation à ce sujet. En particulier, il y a aussi une règle de 14,2 / 14: P> Deux types de struct (clause 9) sont compatibles layouche si elles ont le même nombre de membres de données non statiques, et les éléments de données non statistiques correspondants (dans l'ordre) ont des types compatibles de mise en page (3.9). P>
blockquote> Par conséquent, si vous avez quelque chose comme: p> Il est nécessaire d'être la mise en page compatible avec: p> #pragma pack (n) code>), mais il varie entre les compilateurs. P>
y code> et
z code> signifie qu'ils pourraient être théoriquement commandés. Je suis à peu près sûr que c'est purement théorique mais je ne connais aucun compilateur qui réoriente les membres de cette situation (et à moins que la mémoire ne me manque plus d'habitude aujourd'hui, ceci est fixé en C ++ 0x). p>
public: code>, le premier membre que vous définissez doit venir en mémoire en mémoire. D'autres membres séparés par
Public: Code> Spécificateurs pourrait être théoriquement être réarrangé. P>
struct B {
int x;
int y;
int z;
};
Le bit de réorganisation semble troublant. J'aimerais avoir une référence à la partie pertinente de la norme pour cela.
Je pensais que tous les membres d'une structure étaient publics par défaut, privé dans une classe.
Oui, ils sont. Dans ce cas, les spécificateurs d'accès sont entièrement volus dans la mesure où la spécification d'accès va - elles sont toujours autorisées, et comme indiqué ci-dessus, ils signifient toujours quelque chose, tout ce qui n'est rien lié à la spécification de l'accès.
Si vous souhaitez voir la disposition de la mémoire de tous les types de classe en mémoire sous MSVC, ajoutez le commutateur Si vous voulez voir quelle classe est posée comme, ajoutez / d1reporallllasslayout d1reporallllasslayout d1reporallallclasslayout d1reporallllasslayout d1reporallllasslayout d1reporallllasslayout sur la ligne de commande compiler. p>
/ d1reportsingleclasslayoutnnnnn code> où
nnnnn code> est le nom de la classe. P>
Vous avez de plus gros problèmes. L'alignement des tas n'est généralement pas meilleur que 8 par exemple. __declSpec (alignement) et _aligned_malloc () sur MSVC.
Vous voudrez peut-être essayer d'écrire un code simple qui accède à tous les membres d'une structure et regardez la sortie de l'assembleur de votre compilateur (-S pour GCC, si je me souviens bien) de voir comment l'accès se produit.
@HANS: Nous faisons l'alignement à la main pour cette raison.