Selon la norme C ++, un Je suis très intéressé - il existe un exemple réel d'une implémentation C ++ lors de la diffusion d'un pointeur à un autre type de pointeur avec REINIERPRET_CAST CODE> d'un pointeur
T * code> à un autre pointeur de type
q * code> Can Modifier ou ne pas modifier la valeur du pointeur en fonction de la mise en œuvre. P>
REINERPRET_CAST CODE> modifie le pointeur? Quoi et pourquoi est changé là-bas? P>
5 Réponses :
Notez que lorsque la norme stipule qu'il peut ou ne peut pas faire quelque chose, cela ne signifie pas qu'il y a une implémentation actuelle qui a ce comportement, seulement qu'ils pourraient.
Le plus proche que je puisse penser est un L'architecture où l'alignement de type était requis par le matériel et une implémentation qui a décidé de corriger l'alignement si nécessaire. Quelque chose comme: p> Il pourrait y avoir une exigence que pour A code> soit un pointeur valide, il doit adresser une position de mémoire de 8, tandis que L'argument
q code> avec des exigences d'alignement moindre pourrait indiquer n'importe quelle adresse mémoire. p> p>
class A1 { int a1; }; class A2 { int a2; }; class B: public A1, public A2 { }; #define DBG(val) cout << #val << ": " << val << endl // test code B b; DBG(&b); // prints 0x42 void *p_blank = &b; DBG(p_blank); // prints 0x42 A2 *p_a2 = &b; DBG(p_a2); // prints 0x46 void *p_reinterpreted = reinterpret_cast<A2*>(&b); DBG(p_reinterpreted); // prints 0x42 A2 *p_reinterpreted2 = reinterpret_cast<A2*>(&b); DBG(p_reinterpreted2); // prints 0x42 A2 *p_a2 = &b means give me the pointer to an A2 object within the B object. reinterpret_cast<A2*>(&b) means give me the pointer to b and treat it as an A2 pointer. The result of this reinterpret_cast has the type 'pointer to A2', therefore it produces no warning when assigned to a void* variable (or to a A2* variable).
Dans votre exemple, le REINERPRET_CAST CODE> ne change pas le tout de la valeur ... Vous êtes d'accord, j'ai peur.
Dans A2 * p_a2 = & B; code> Vous utilisez une conversion implicite équivalente à
static_cast code>, pas
REINIERPRET_CAST code>.
Il semble que je n'ai pas compris la question correctement. J'ai compris que vous recherchez un cas où réinterpret_cast <> renvoie une valeur différente de celle d'une "adresse" vide ". Je n'ai pas trouvé de clause dans la norme C ++ qui permet à ce que REINERPRET_CAST
@akira: Lorsque vous effectuez une option implicite (ou static_cast >) à un pointeur de base, le pointeur renvoyé est l'adresse de la sous-classe de cette base dans l'objet. Lorsque vous faites cela avec la première base, les adresses coïncident. S'il y a de multiples héritage, de l'injection à tout sauf la première base (en supposant que la première classe de base n'est pas vide) produira des pointeurs décalés. Dans cet exemple particulier, la classe
A1 code> prend exactement 4 octets.
Reterpret_cast ne retournera jamais une adresse différente - il est nécessaire de copier l'adresse exacte. p>
Dans les cas de héritage multiple, comme David Rodriguez dit, la prise de l'adresse de l'une des bases peut renvoyer une adresse compensée à l'adresse de la première base. Reterpret_cast retournera cette adresse de compensation, mais si vous le traitez comme l'adresse de l'obstruction, l'enfer s'ensuivra. p>
Pour la refoulement, Static_cast peut renvoyer une adresse différente de celle donnée. Si l'adresse que vous avez est l'une des bases et que cette adresse est en cours d'offset à la première adresse de base, Static_cast retournera une adresse valide pour l'objet prémjectif, ce qui est égal à l'adresse de la première base et donc pas égale à égale. au pointeur passé. P>
Pour ce faire court: Reterpret_cast vous donne la même adresse, toujours. Static_cast et dynamic_cast peuvent renvoyer une adresse différente, par ex. Dans certains cas impliquant plusieurs héritages. P>
La différence entre static_cast et dynamic_cast est que static_cast ne vérifie pas si le pointeur que vous donnez est le bon objet pour la distribution, alors assurez-vous de cela avant de l'appeler. P>
Une déclaration impliquant des "obligatoires" doit être sauvegardée avec une source. Tout ce que je vois, c'est que vous êtes autorisé à convertir en un pointeur de type moins aligné puis de retour i>, et "le résultat de toute autre conversion de ce pointeur n'est pas spécifiée". (5.2.10 / 7)
Euh, j'ai complètement manqué les problèmes d'alignement, je peux voir comment cela changerait l'adresse. Merci pour la correction.
La source de problèmes la plus probable est sur une machine de vecteur où les opérations scalaires sont définies en termes de vecteurs et qu'un pointeur scalaire consiste en un pointeur pour vecteur avec un index dans le vecteur. Historiquement, l'architecture de crayon originale était comme celle-ci et cela a causé des maux de tête. De nos jours, vous pourriez voir quelque chose comme ça sur un GPU, mais je ne peux pas signaler quelque chose de spécifique au sommet de ma tête. P>
L'effet le plus probable est la troncature car le type de pointeur de destination manque de bits pour spécifier la partie index. C ++ 11 donne un signe de tête dans cette direction en permettant à tous les types de pointeur d'être Un pointeur d'objet peut être explicitement converti en un pointeur d'objet de
un type différent. Quand une prvalue V de type "pointeur à t1" est
converti en type "pointeur à cv t2", le résultat est REINIERPRET_CAST CODE> ED Tant qu'ils ont les mêmes besoins d'alignement. Les bits "zerés" par alignement rigoureux sont autorisés à ne pas exister. P>
static_cast
Je ne pense pas que la question soit de manière significative différente pour les moulages de pointeur C ++ contre c. De Cette réponse a > Je ne cite qu'un des exemples: p>
La série Eclipse MV de données Général dispose de trois formats de pointeur (mot, octets et points de bits), dont deux sont utilisés par C compilateurs: des pointeurs d'octets pour qui suggère un
char * code> et
Void * code> et moteurs de mots pour tout le reste p>
blockQuote>
réinterpret_cast
Vous voulez dire, "change la valeur" le pointeur pointe?
@akira: Non, modifie la valeur du pointeur lui-même
Vous voulez dire comme:
t * t = 0x13; Q * q = 0x42; t = reintrepret_cast
@akire: Je suppose, oui. Je ne suis pas sûr de moi, c'est pourquoi je demande. Vous pourriez être intéressé à lire les réponses à la question liée - ils m'ont inspiré à poser cette question.
Donc, vous n'êtes pas sûr de ce que vous demandez? :) Je pense que les réponses supprimées résultaient de la question légèrement incertaine. Oui, la question liée est intéressante.