Gibt es einen Unterschied zwischen den folgenden drei Umwandlungen zum Extrahieren von rohen Bytezeigern zur Verwendung in Zeigerarithmetik? (Unter der Annahme einer Plattform, wo char 1 Byte ist.)reinterpret_cast <char*> (p) oder static_cast <char*> ((void *) p)) für byteweise Zeigerdifferenz, was ist besser?
static_cast<char*>((void*)ptr))
reinterpret_cast<char*>(ptr)
- (aktualisiert) oder:
static_cast<char*>(static_cast<void*>(ptr))
Was sollte ich bevorzugen?
mehr Details ...
Da Zeiger auf zwei Mitgliedsobjekte in einer Klasse, würde Ich mag ein von einem zum anderen versetzt berechnen, so dass ich angesichts der Adresse eines Mitglieds rekonstruieren ein Offset und die Adresse des anderen Mitglieds.
// assumed data layout:
struct C {
// ...
A a;
// ...
B b;
}
Der Code, den ich im Moment verwenden ist entlang der Linien von:
void approach1(A *pa, B *pb)
{
// compute offset:
std::ptrdiff_t offset = static_cast<char*>((void*)pa) - static_cast<char*>((void*)pb);
// then in some other function...
// given offset and ptr to b, compute ptr to a:
A *a = static_cast<A*>((void*)(static_cast<char*>((void*)pb) + offset));
}
main()
{
C c;
approach1(&c.a, &c.b);
}
Ich möchte wissen, ob die folgende ist besser (oder schlechter):
void approach2(A *pa, B *pb)
{
std::ptrdiff_t offset = reinterpret_cast<char*>(pa) - reinterpret_cast<char*>(pb);
// ...
A *a = reinterpret_cast<A*>(reinterpret_cast<char*>(pb) + offset);
}
Sind die beiden Methoden völlig gleichwertig? Sind sie genauso tragbar?
Mein Eindruck ist, dass approach1()
ist tragbarer, weil "static_cast
ing a pointer to and from void*
preserves the address", während reinterpret_cast<>
weniger garantiert (siehe angenommene Antwort bei Link).
Ich würde gerne wissen, was der sauberste Weg ist, dies zu tun ist.
Update: Erklärung des Zwecks
Eine Reihe von Menschen hat gefragt, was ist der Zweck, diese Offsets zu berechnen. Der Zweck besteht darin, eine Meta-Klasse-Tabelle mit Instanz-Offsets zu erstellen. Dies wird von einem Laufzeit-Reflektionsmechanismus zur automatischen GUI-Erstellung und Persistenz verwendet (die Offsets werden nicht serialisiert, sondern nur zum Durchlaufen der Struktur verwendet). Der Code ist seit über 15 Jahren in Produktion. Für die Zwecke dieser Frage möchte ich nur die portabelste Art der Berechnung der Zeigeroffsets wissen. Ich habe nicht die Absicht, große Änderungen an der Funktionsweise des Metaklassensystems vorzunehmen. Darüber hinaus bin ich im Allgemeinen auch an der besten Möglichkeit interessiert, dies zu tun, da ich andere Anwendungen im Sinn habe (z. B. Differenzzeiger für einen Code für gemeinsam genutzten Speicher).
HINWEIS: Ich kann nicht offsetof()
verwenden, weil in meinem eigentlichen Code nur ich die Zeiger auf Instanzen haben a
und b
, ich habe nicht unbedingt den Typ des enthaltenen Objekts c
oder andere statische Informationen offsetof()
zu verwenden. Alles was ich annehmen kann ist, dass a
und b
Mitglieder desselben Objekts sind.
C++ 11 oder nicht? einige Besonderheiten von reinterpret_cast haben IIRC geändert. Abgesehen davon: Warum willst du das machen? – stijn
Dies könnte ein wenig helfen http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used – displayname
@stijn C++ 03 oder früher bevorzugt.Antworten, die die Unterschiede zwischen verschiedenen C++ - Versionen erklären, würden mir gefallen, damit ich es verstehen kann. Ich werde die Frage mit einer Beschreibung des Zwecks aktualisieren. –