Nein, uintptr_t
nicht Bedeutung verwendet werden können, zu vermeiden, undefiniertes Verhalten bei der Zeigerarithmetik.
Zum einen, zumindest in C gibt es keine Garantie, dass uintptr_t
überhaupt existiert. Voraussetzung ist, dass ein beliebiger Wert vom Typ void*
in uintptr_t
und zurück konvertiert werden kann, wodurch der ursprüngliche Wert ohne Informationsverlust erreicht wird. Im Prinzip ist möglicherweise kein vorzeichenloser Integertyp vorhanden, der breit genug ist, um alle Zeigerwerte zu enthalten. (Ich nehme an, das gleiche gilt für C++, da C++ den größten Teil der C-Standardbibliothek erbt und durch Verweis auf den C-Standard definiert.)
Auch wenn uintptr_t
existiert, gibt es keine Garantie, dass eine gegebene arithmetische Operation auf a Wert tut das gleiche wie die entsprechende Operation auf einen Zeigerwert.
Zum Beispiel habe ich an Systemen (Cray Vektorsysteme, T90 und SV1) gearbeitet, auf denen Bytezeiger in Software implementiert sind. Eine native Adresse ist eine 64-Bit-Adresse, die sich auf ein 64-Bit-Wort bezieht. Es gibt keine Hardwareunterstützung für die Byteadressierung. Ein Zeiger char*
oder void*
besteht aus einem Wortzeiger mit einem 3-Bit-Offset, der in den ansonsten nicht verwendeten höherwertigen Bits gespeichert ist. Die Konvertierung zwischen Ganzzahlen und Zeigern kopiert einfach die Bits. Wenn man also ein char*
inkrementiert, würde es so weit fortschreiten, dass es auf das nächste 8-Bit-Byte im Speicher zeigt; Inkrementieren eines uintptr_t
, erhalten durch Umwandeln eines char*
, würde es voranbringen, um auf das nächste 64-Bit-Wort zu zeigen.
Das ist nur ein Beispiel. Ganz allgemein sind Konvertierungen zwischen Zeigern und Ganzzahlen implementationsdefiniert, und der Sprachstandard gibt keine Garantie für die Semantik dieser Konvertierungen (außer in einigen Fällen, die zurück in einen Zeiger konvertiert werden).
Also ja, Sie können einen Zeigerwert in uintptr_t
konvertieren (wenn dieser Typ vorhanden ist) und arithmetische Berechnungen durchführen, ohne ein undefiniertes Verhalten zu riskieren - aber das Ergebnis kann bedeutungsvoll sein oder auch nicht.
Es passiert, dass auf den meisten Systemen, die Zuordnung zwischen Zeigern und Ganzzahlen ist einfacher, und Sie können wahrscheinlich mit dieser Art von Spiel kommen . Aber Sie sollten lieber direkt mit Zeigerarithmetik arbeiten und nur sehr vorsichtig sein, um ungültige Operationen zu vermeiden.
Also 'reinterpret_cast (offset_p-offset + n_less_equal_array_size)' ist immer gut ertragen, wo offset_p den versetzten ptr-Wert in std :: uintptr_t speichert? – Jamboree
Nicht sicher, ob ich folge. Aber die allgemeine Antwort ist, wenn die ganze Zahl, die du an "reinterpret_cast" übergibst, der gleiche Wert ist wie der, den du daraus erhalten hast, dann ist es legal. Wenn nicht, dann ist es illegal. –
Für das erste Element von Array ist es derselbe Wert, aber ich möchte wissen, ob es auch für andere Elemente im Array funktioniert. – Jamboree