2010-01-25 7 views

Répondre

2

a est casté à un char*&. Il est appelé reinterpret_cast parce que les bits sont réinterprétés exactement de la manière demandée par le type cible de cast. Le compilateur ne vérifie pas la validité (et ne pourrait pas le faire). Cela ramène un pointeur à ses origines: c'est juste une adresse d'un morceau de mémoire.

La raison a est castée à une référence à un pointeur est qu'une référence est nécessaire pour avoir une lvalue valide à affecter cp à. reinterpret_cast<char *>(a) = cp aurait été illégale parce que vous ne pouvez pas attribuer à un temporaire.

Il semble un peu moche dans le code source. Celui-ci:

char* c = reinterpret_cast<char*>(a); 
c = cp; 

est sans doute préférable de maintenir et de lire, bien qu'il soit plus (notez ce n'est pas exactement le même sens que nous introduisons une variable c supplémentaire pour maintenir le résultat de la distribution dans l'échantillon original. La mémoire de a est réutilisée pour pointer vers le nouvel emplacement cp).

+1

Cela n'aurait probablement pas la même signification. Dans le code de la question, la valeur de 'a' change pour pointer vers, alors que dans votre code la valeur de' a' reste inchangée. La façon de rendre le code plus facile à lire et de garder le sens est en fait le type de pointeur de 'a' (supposons que' a' est 'T *'): 'a = reinterpret_cast (cp);'. Le casting dans le RHS ne nécessite pas de référence lvalue, un simple rvalue suffit et ainsi le '&' peut être enlevé. –

+0

Vous avez raison, mon extrait a été mal formé. Edité juste un peu pour convenir à mon explication. Le vôtre est le meilleur moyen. –

0

Certaines personnes sont confuses au sujet de la référence dans la distribution. Sans la référence, nous aurions quelque chose comme ceci:

T a; // whatever a is, we don't know 
char* cp; // or something convertible to char* 

// remember, this is not what actually gets generated 
char* some_temporary_rvalue = reinterpret_cast<char*>(a); 
some_temporary_rvalue = cp; // illegal, and senseless 

Avec la référence, il devient:

T a; // whatever a is, we don't know 
char* cp; // or something convertible to char* 

char*& a_treated_as_charptr = reinterpret_cast<char*&>(a); 
a_treated_as_charptr = cp; // assigns a char* that is at &a 
+0

Pourquoi 'a_treated_as_charptr' n'est-il pas une référence à un temporaire? Ou est-ce la référence qui * garde * la portée temporaire? –

+0

Et pourquoi devons-nous jeter 'a' à un' * & '? Pourquoi ne pouvons-nous pas simplement dire: 'char * & a_treated_as_charptr = reinterpret_cast (a);'? –

+0

STingRay: C'est la référence dans la distribution qui empêche 'reterpret_cast' de créer un rvalue. Avec une référence, il dit "traiter cette zone de mémoire comme ce type"; sans cela, il dit, "traiter la valeur de cette zone dans la mémoire comme ce type" En fait, votre deuxième commentaire est illégal et ne compilera pas. Vous attribueriez une référence à une variable temporaire. (Essayez le même processus que dans mon post.Vous diriez 'char * & a_treated_as_charptr = some_temporary_rvalue') – GManNickG

-1

La partie intéressante, manque de la question est le type de a. Je peux juste supposer que c'est une sorte de pointeur (cela peut être n'importe quoi, mais cette hypothèse rend la discussion plus simple).

T *a; 
char* p = "Hello"; 
reinterpret_cast<char*&>(a) = p; 

Dans l'hypothèse où a est en fait un pointeur à un autre type, le résultat de l'opération serait équivalent à:

T *a; 
char *p = "Hello"; 
a = reinterpret_cast<T*>(p); // convert p to a T* and assign 

la différence étant que dans la première version, la distribution est étant effectué sur le côté gauche (LHS) de l'affectation et doit donc être un cast à une référence (lvalue), tandis que dans le second cas, la distribution est effectuée sur le côté droit (RHS) et donc un rvalue suffit et là n'est pas nécessaire de lancer à une référence.

Maintenant, dans le cas général, il y a des différences dans les deux castes. Réinterpréter la distribution réinterprétera simplement la mémoire comme le type que vous lui donnez. Si le type a et char* sont de la même taille (ce qui, selon l'hypothèse ci-dessus, est valable, tous les pointeurs ont la même taille), alors les deux opérations sont identiques et donnent le même résultat. Par contre, si un type est plus grand que l'autre alors les deux opérations ne sont pas équivalentes. Si sizeof(a) > sizeof(char*) la première version va réinterpréter la variable et remplacer uniquement les premiers sizeof(char*) octets de a avec la valeur de p.Dans le second cas, il lira sizeof(a) octets à partir de l'emplacement de mémoire de p (provoquant un comportement indéfini, car il lira au-delà de la variable) et copiera ces octets en écrasant tous les octets précédents en a.

Le contraire va se sizeof(a) < sizeof(char*) alors la première version écrasera au-delà de l'espace alloué pour a provoquant un comportement non défini, tandis que le second remplacera a avec les premiers sizeof(a) octets dans p.

Questions connexes