8
votes

Les références aux mêmes classes de base doivent avoir des compensations séparées en mémoire

J'ai découvert certaines incohérences entre compilateurs avec ce programme, xxx

la plupart des compilateurs affirment sur la taille de (c) == 8 disant que la taille de (c) est en réalité 12. Le seul Compilateur J'ai trouvé que cela ne dit pas et dit que c'est 8 est Microsoft Visual Studio 2010.

La raison à laquelle je me suis dit, par quelqu'un plus intelligent, est-ce qu'il y a deux références distinctes d'un B Besoin de conserver des compensations individuelles différentes les unes des autres. Tout d'abord, l'A dérivé de C est en décalage 0 et la seconde A de l'intérieur B ne peut pas être au même décalage que le premier A à 0 SO 4 octets de rembourrage est inséré.

Comme la plupart des compilateurs ont mis en œuvre ce comportement, je me demandais dans quelle mesure avez-vous besoin de vous assurer que les deux ont des références différentes? Vous recherchez une certaine intuition sur la raison pour laquelle c'est le cas?

Quelqu'un a dit que cela peut être une condition requise par la norme et nous étions curieux de savoir quelle est la raison de celle-ci?

Merci


1 commentaires

Incohérences entre les compilateurs C ++? Mes mes nouvelles.


3 Réponses :


3
votes

Oui, cela est mentionné à 10P8:

Une classe de base SubObject peut être de taille zéro (clause 9); Cependant, deux subœuvres qui ont le même type de classe et qui appartiennent à la même chose L'objet le plus dérivé ne doit pas être attribué à la même adresse (5.10) .

in C Vous avez deux A S, on est hérité et l'autre fait partie de B . Microsoft utilise de manière agressive et à tort l'optimisation de la classe de base vide ici quand elle ne devrait pas. Je crois que c'est un bogue connu, mais il est vraiment difficile de trouver le rapport de bogue sur Microsoft Connect.


4 commentaires

Ok, donc cela fait partie de la norme, mais savez-vous pourquoi il a été ajouté? Il doit y avoir une raison pour que cela soit le cas?


@CoderDave Si vous êtes intéressé par le raisonnement de la décision de conception, vous devez marquer ce langage-avocat.


@CoderDave: Comme indiqué dans 5.10: Deux pointeurs du même type comparent égal si et seulement s'ils sont tous les deux nuls, les deux pointent sur la même fonction, ou les deux représentent la même adresse afin que cela signifierait que Deux pointeurs à deux objets différents du même type comparaient l'égalité qui n'est pas autorisée. Un exemple vérifie l'auto-affectation (ceci! = & Autre) .


@Jessegood Merci a du sens!



3
votes

La norme nécessite définitivement que l'adresse de chaque objet du même type est différente. La clause pertinente est 5.10 [EXPR.EQ] Paragraphe 1:

Deux pointeurs du même type comparent égal si et seulement s'ils sont tous les deux nuls, les deux pointent sur la même fonction, ou les deux représentent la même adresse (3.9.2).

Ceci est nécessaire pour distinguer les deux objets. Les objets ont à la fois une valeur et une identité. Pour une classe de base SubObject, il est raisonnable d'avoir la même adresse que la classe contenant. Pour un membre d'une classe, vous pouvez distinguer l'identité des deux objets par leur type, c'est-à-dire qu'il s'agit d'avoir la même adresse. Pour deux objets du même type, vous avez toujours besoin de quelque chose pour distinguer les objets pour leur identité.


0 commentaires

1
votes

en C ++, un objet est déterminé de manière unique par une paire de données: son adresse et son type.

Comme vous l'avez observé à juste titre, C et d contiennent deux sous-observations distinctes A pour lequel cela doit être vrai. Toutefois, en fonction de la manière dont vous posez B en mémoire, vous pouvez voir comment il pourrait ne pas être possible de mettre les deux a -subobjects à différentes adresses dans une structure de 8 octets dans une structure de 8 octets .

Pourquoi n'imprimez-vous pas les adresses numériques réelles des sous-observations?


0 commentaires