Sowohl static_cast als auch reinterpret_cast scheinen gut zu funktionieren, um void * in einen anderen Zeigertyp umzuwandeln. Gibt es einen guten Grund, einander vorzuziehen?
202
Sowohl static_cast als auch reinterpret_cast scheinen gut zu funktionieren, um void * in einen anderen Zeigertyp umzuwandeln. Gibt es einen guten Grund, einander vorzuziehen?
Antworten:
Verwendung
static_cast
: Es ist die engste Besetzung, die genau beschreibt, welche Konvertierung hier vorgenommen wird.Es gibt ein Missverständnis, dass die Verwendung
reinterpret_cast
besser zusammenpassen würde, da dies bedeutet, dass die Typensicherheit vollständig ignoriert und nur von A nach B geworfen wird.Dies beschreibt jedoch nicht die Wirkung von a
reinterpret_cast
. Hat vielmehrreinterpret_cast
eine Reihe von Bedeutungen, für die alle besagen, dass „das von durchgeführte Mappingreinterpret_cast
implementierungsdefiniert ist“. [5.2.10.3]Aber im besonderen Fall des Castings von
void*
bisT*
zum Mapping ist der Standard völlig genau definiert; nämlich einem typlosen Zeiger einen Typ zuzuweisen, ohne dessen Adresse zu ändern.Dies ist ein Grund zu bevorzugen
static_cast
.Darüber hinaus und wohl wichtiger ist die Tatsache, dass jede Verwendung von
reinterpret_cast
geradezu gefährlich ist, da sie alles wirklich in etwas anderes umwandelt (für Zeiger), während siestatic_cast
viel restriktiver ist und somit ein besseres Schutzniveau bietet. Dies hat mich bereits vor Fehlern bewahrt, bei denen ich versehentlich versucht habe, einen Zeigertyp in einen anderen zu zwingen.quelle
Das ist eine schwierige Frage. Einerseits macht Konrad einen hervorragenden Punkt in Bezug auf die Spezifikationsdefinition für reinterpret_cast , obwohl es in der Praxis wahrscheinlich dasselbe tut. Wenn Sie dagegen zwischen Zeigertypen wechseln (wie dies beispielsweise bei der Indizierung im Speicher über ein char * üblich ist), generiert static_cast einen Compilerfehler und Sie müssen ohnehin reinterpret_cast verwenden .
In der Praxis verwende ich reinterpret_cast, weil es die Absicht der Cast-Operation besser beschreibt. Sie könnten sich durchaus dafür einsetzen, dass ein anderer Operator nur Zeiger-Neuinterpretationen festlegt (die die gleiche zurückgegebene Adresse garantieren), aber es gibt keine im Standard.
quelle
reinterpret_cast
!Ich schlage vor, immer die schwächste Besetzung zu verwenden.
reinterpret_cast
kann verwendet werden, um einen Zeiger auf a zu werfenfloat
. Je strukturbrechender die Besetzung ist, desto mehr Aufmerksamkeit erfordert ihre Verwendung.Im Falle von
char*
würde ich eine Besetzung im C-Stil verwenden, bis wir welche habenreinterpret_pointer_cast
, weil sie schwächer ist und nichts anderes ausreicht.quelle
float f = *reinterpret_cast<const float*>(&p);
float
, was falsch ist. Der Ausdruck Abgüssevoid **
zuconst float *
und verwendet dann einen dereferenzieren Betrieb (das ist kein cast), zu konvertierenconst float *
zufloat
.Meine persönliche Präferenz basiert auf Code-Kenntnissen wie folgt:
oder
Am Ende machen beide dasselbe, aber static_cast scheint in einer Middleware-App-Umgebung angemessener zu sein, während eine Neuinterpretation der Besetzung eher etwas ähnelt, das Sie meiner Meinung nach in einer Bibliothek auf niedrigerer Ebene sehen würden.
quelle