Die allgemeine Folklore sagt:
Das Typsystem existiert aus einem Grund. Ganzzahlen und Zeiger sind unterschiedliche Typen. Das Umsetzen zwischen ihnen ist in den meisten Fällen ein Fehlverhalten, kann auf einen Entwurfsfehler hinweisen und sollte vermieden werden.
Selbst wenn eine solche Besetzung durchgeführt wird, werden keine Annahmen über die Größe von ganzen Zahlen und Zeiger gemacht werden (Gießen
void*
aufint
die einfachste Art und Weise der Code nicht auf x64 zu machen), und stattint
eines verwenden sollteintptr_t
oderuintptr_t
ausstdint.h
.
Wenn man das weiß, wann ist es tatsächlich nützlich , solche Casts durchzuführen?
(Hinweis: Ein etwas kürzerer Code für den Preis der Portabilität gilt nicht als "tatsächlich nützlich".)
Ein Fall, den ich kenne:
- Einige sperrfreie Multiprozessor-Algorithmen nutzen die Tatsache aus, dass ein 2 + -Byte-zugeordneter Zeiger eine gewisse Redundanz aufweist. Sie verwenden dann beispielsweise die niedrigsten Bits des Zeigers als boolesche Flags. Bei einem Prozessor mit einem geeigneten Befehlssatz kann dies die Notwendigkeit eines Sperrmechanismus beseitigen (was erforderlich wäre, wenn der Zeiger und das Boolesche Flag getrennt wären).
(Hinweis: Diese Vorgehensweise kann in Java sogar sicher über java.util.concurrent.atomic.AtomicMarkableReference durchgeführt werden.)
Noch etwas?
intptr_t
Implementierung ist definiert, sodass ich den sperrfreien Algorithmus auch nicht verwenden würde, wenn ich nicht genau wüsste, auf welchem Compiler er ausgeführt werden würde.