Ist eine Pointer Konvertierung eine Operation?
-
Hallo,
Ist bekannt ob einer Pointer Konvertierung in c++ eine tatsächliche Operation auf der cpu folgt? Im Prinzip ändert die Konvertierung ja lediglich das Verhalten mit dem der Compiler zb. die Pointer Adresse inkrementiert usw., an der tatsächlichen Pointer Adresse ändert sich ja nichts.
-
Der Standard selbst schweigt sich über solche Dinge (aus gutem Grund) aus; Implementationsdetails dieser Art bleiben den einzelnen Compilerbauern überlassen. Diese sind aber im Allgemeinen bemüht, unnötigen Overhead zu vermeiden, so dass man davon ausgehen kann, dass dort, wo eine Konvertierung nicht notwendig ist, diese auch nicht geschieht.
Konkret bedeutet das: Wenn der numerische Wert des Zeigers, den man castet, sich durch den Cast nicht ändert (also von Seiten der CPU nichts getan werden muss), wird ein Compiler keinen Code dafür generieren. Das ist in der Regel der Fall; aus dem Stand fällt mir nur bei multipler Vererbung ein anderes Verhalten ein:
struct A { char filler; int data; }; struct B { char filler; int data; }; struct C : A, B { }; C c; C *pc = &c; A *pa = pc; // <-- hier B *pb = pc; // <-- oder hierDa c hier zwei Basisklassenobjekte beinhaltet, die nicht an der selben Stelle liegen können, wird einer der Basisklassenzeiger nicht an den Anfang des umgebenden Objektes zeigen können. In diesem Fall ist eine Konvertierung auf Maschinenebene notwendig (ein fester Wert muss auf den Zeiger addiert werden). Wie das genau aussieht, ist allerdings nicht so einfach vorherzusehen, da ein optimierender Compiler durchaus schlau sein kann. Wenn ich zum Beispiel
static_cast<A*>(pc)->data = 0; static_cast<B*>(pc)->data = 1;schreibe, wird (jetzt unter der Annahme, dass B das Basisklassenobjekt ist, das nicht am Anfang von c leigt) der Compiler beim Zugriff auf c.B::filler mit einiger Wahrscheinlichkeit nicht erst static_cast<B*>(pc) ausrechnen, um dann data aus dem Objekt herauszusuchen, sondern das in einem Rutsch erledigen, so dass beide Zeilen mit der gleichen Anzahl an Instructions auskommen.
Oh, und natürlich wird dynamic_cast einiges an Typprüfung und unter Umständen (insbesondere Umständen mehrfacher oder virtueller Vererbung) einiges an Gehangel durch einen Objektbaum durchführen. Aber wenn du dynamic_cast brauchst, ist mit deinem Design sowieso etwas nicht in Ordnung.
-
EDIT: Hier stand Mist.
-
Danke erstmal für die Antwort,
Aber angenommen ich arbeite mit void Pointern und verwende auch keine polymorphen Objekte sondern nur Basisdatentypen in die Konvertiert werden soll, ich weiß das mit dem void pointer könnte man auch mit templates lösen, dennoch, sollten die Pointer Konvertierungen in irgend einer Form Zeit in anspruch nehmen?
-
Wie seldon bereits geschrieben hat, prinzipiell kommt das auf dein System an, der Standard macht darüber keine Aussage, aber auf allen handelsüblichen Systemen passiert da gar nichts.
-
Die Addresse bleibt gleich, die Konvertierung wirkt sich nur auf den COmpiler aus, weil der mit dem Pointer anders umgehen muss.
Auf Maschinenebene bleibt alles gleich. Da gibt es noch nicht einmal Datentypen, sondern nur Speichergrößen, und die bleiben natürlich gleich.
Das gilt natürlich nur für static_cast, reinterpret_cast, const_cast und den C-Style-cast, nicht für dynamic_cast oder eigene ähnliche Implementieren, wie boost:lexical_cast.
-
Marthog schrieb:
Auf Maschinenebene bleibt alles gleich. Da gibt es noch nicht einmal Datentypen, sondern nur Speichergrößen, und die bleiben natürlich gleich.
Das gilt natürlich nur für static_cast, reinterpret_cast, const_cast und den C-Style-castIch biete
static_cast<double>(int_value).
-
@SeppJ: Hier ist von Pointern die Rede, da hat Marthog schon recht.