ich die Rückseite setzen wollen und her unter @Bathsheba's post ruhen. Also hier ist eine Antwort über die feineren Details von dem, was Sie tun.
@Sean already suggested Sie reinterpret_cast
Ihre Zeiger statt. Und das ist gleichbedeutend mit deiner zweiten Verkettung. Es sagt so viel in [expr.reinterpret.cast]/7:
Ein Objektzeiger kann explizit auf einen Objektzeiger von eine andere Art umgewandelt werden. Wenn ein Prvalue v
des Objekt-Zeigertyps in den Objektzeiger Typ "Zeiger auf CV T
" konvertiert wird, ist das Ergebnis static_cast<cv T*>(static_cast<cv void*>(v))
. [Anmerkung: Konvertieren eines prvalue des Typs „Zeiger auf T1
“ auf den Typ „Zeiger auf T2
“ (wobei T1
und T2
Objekttypen sind und wobei die Ausrichtungsanforderungen der T2
sind nicht strenger als die von T1
) und zurück zu Der ursprüngliche Typ liefert den ursprünglichen Zeigerwert . - Endnote]
Nun untersuchen wir jeden Schritt der zweistufigen Umwandlung. Zuerst haben wir eine static_cast<void*>
. Nach [conv.ptr]/2 (Hervorhebung von mir):
A prvalue des Typs „Zeiger auf cv T
“, wobei T
ein Objekttyp ist, kann auf eine prvalue des Typs „Zeiger auf cv void
“ umgewandelt werden. Der Zeigerwert ist durch diese Konvertierung unverändert.
Die erste Konvertierung ändert nichts an der Adresse.Und dann heißt es auch in [basic.compound]/5:
Ein Zeiger auf cv-qualifiziert oder cv-unqualifizierten void
kann verwendet werden, um Objekte unbekannter Art zu zeigen. Ein solcher Zeiger soll einen Objektzeiger halten können. Ein Objekt vom Typ cv void*
muss dieselben Anforderungen an die Darstellung und Ausrichtung haben wie , cv char*
.
So ein char*
speichern kann jede Adresse ein void*
speichern. Nun heißt das nicht, dass die Konvertierung von void*
zu char*
wertschonend ist, nur dass sie die gleichen Werte repräsentieren können. Unter der Annahme eines sehr eingeschränkten Anwendungsfalls ist dies eine Garantie. Aber es gibt mehr zu [expr.static.cast]/13:
A prvalue vom Typ „Zeiger auf cv1 Leere“ kann vom Typ „Zeiger auf cv2 T“ zu einem prvalue umgewandelt werden, wobei T ein Objekttyp und cv2 das ist gleiche cv-Qualifikation als oder höhere cv-Qualifikation als, cv1. Wenn der ursprüngliche Zeigerwert die Adresse A eines Bytes in Speicher darstellt und A die Ausrichtungsanforderung von T nicht erfüllt, dann ist der resultierende Zeigerwert nicht spezifiziert. Andernfalls, wenn der ursprüngliche Zeigerwert auf ein Objekt a zeigt und es ein Objekt b vom Typ T (Ignorieren von cv-qualification) gibt, das mit a, Zeiger-interkonvertierbar ist, ist das Ergebnis ein Zeiger auf b. Andernfalls ist der Zeigerwert unverändert durch die Konvertierung.
Wohin gehe ich damit? Unter der Annahme, pc
hält bereits die Adresse eines int
(geeignet entsprechend dem oben genannten umgewandelt), dann Gießen der char*
zu einem int*
über reinterpret_cast
wird Ihnen die Adresse des ursprünglichen int
geben. Die Note unter dem ersten Absatz sagt so viel aus, und die weiteren Zitate beweisen es. Wenn es nicht die Adresse eines int
hält, spielen Sie Roulette und werden wahrscheinlich verlieren. Ihr Programm hat ein undefiniertes Verhalten. Sie sollten Bathsebas Ratschlag auf den Buchstaben folgen.
Zunächst, warum versuchen Sie dies zu tun? Es ist kompliziert/eine Warnung, weil es Code riecht. Zweitens, warum bist du mit der zweiten Version unzufrieden? Es funktioniert, oder? –
'(int *) pc' ist kurz, aber es [verbirgt eine heftige Konvertierung] (http://en.cppreference.com/w/cpp/language/explicit_cast). Dein Compiler warnt dich wahrscheinlich, damit du nicht überrascht wirst. Wenn Sie die Konvertierungen explizit buchstabieren, wird davon ausgegangen, dass Sie genau wissen, was Sie tun. – StoryTeller
Was versuchst du eigentlich? Der Zugriff auf einen solchen Zeiger ist (normalerweise) ein undefiniertes Verhalten. Normalerweise müssen Sie einen Weg auslegen, das 'int *' immer zu einem 'char *' zu machen, nicht umgekehrt. – Galik