Funktionspointer casten
-
Das ist meines Wissens nach erlaubt, sofern der Zieltyp "groß genug" ist. Also, es könnte sein, dass auf einem System der Typ uint32_t nicht groß genug zum Speichern einer Adresse Objekt/Funktions-Adresse ist. In dem Fall sollte ein Compiler eine Fehlermeldung ausspucken. Ich weiß allerdings nicht, ob das mit der Fehlermeldung garantiert wird oder ob das Programm dann einfach nicht mehr funktioniert. Der GCC meckert dann jedenfalls.
Ein solcher Cast ist äquivalent zu
reinterpret_cast<uint32_t>(&funktion). Ich würde das auch so aufschreiben, damit deutlich wird, was für eine schmutzige Sache da passiert.
5.2.10 Reinterpret cast:
...
A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementationdefined. [ Note: it is intended to be unsurprising to those who know the addressing structure of the underlying machine. -end note ]
...kk
-
volkard schrieb:
Bei DOS gab es zum Beispiel das Speichermodell Medium, wo Funktionszeiger länger waren als Datenzeiger. Und Compact, wo es andersrum war.
War denn Dein DOS C++ Compiler überhaupt standardkonform?

-
krümelkacker schrieb:
volkard schrieb:
Bei DOS gab es zum Beispiel das Speichermodell Medium, wo Funktionszeiger länger waren als Datenzeiger. Und Compact, wo es andersrum war.
War denn Dein DOS C++ Compiler überhaupt standardkonform?

Logischerweise nicht.
Aber rate mal, weshalb der Standard nicht garantiert, daß Datenzeiger und Funktionszeiger gleich lang sind.
-
Danke schon mal für die vielen guten Antworten. Das Daten und Funktionszeiger unterschiedliche Größen haben können, ist mir bekannt. Das Beispiel mit uint32_t war halt gerade mal auf meiner Plattform so. Ich werde natürlich auf den richtigen Typen einstellen, der in der Lage ist die Daten vollständig aufzunehmen. Läßt sich ja relativ einfach mit C++Metaprogrammingmitteln herausbekommen.
Danke
-
mysterio schrieb:
Danke schon mal für die vielen guten Antworten. Das Daten und Funktionszeiger unterschiedliche Größen haben können, ist mir bekannt. Das Beispiel mit uint32_t war halt gerade mal auf meiner Plattform so. Ich werde natürlich auf den richtigen Typen einstellen, der in der Lage ist die Daten vollständig aufzunehmen. Läßt sich ja relativ einfach mit C++Metaprogrammingmitteln herausbekommen.
DankeDu willst also einen int-Typ für Hashtables.
Dann paßt unsigned long. Oder size_t. Oder decltype(sizeof(0)).
Den Typen würde ich gar nicht berechnen, sondern per Hand festlegen und nur mit einem static_assert absichern. Der ändert sich nämlich nicht oft.
-
mysterio schrieb:
Danke schon mal für die vielen guten Antworten. Das Daten und Funktionszeiger unterschiedliche Größen haben können, ist mir bekannt. Das Beispiel mit uint32_t war halt gerade mal auf meiner Plattform so. Ich werde natürlich auf den richtigen Typen einstellen, der in der Lage ist die Daten vollständig aufzunehmen. Läßt sich ja relativ einfach mit C++Metaprogrammingmitteln herausbekommen.
Moment! Du hast nicht nur interessehalber gefragt, sondern willst das ernsthaft benutzen? Wozu?
-
mysterio schrieb:
Hallo,
ist das casten eines statischen Memberfunktionspointers oder eines Funktionspointers einer freien Funktion in Richtung uintXX_t und wieder in den Orginaltyp zurück Standardkonform?
Zeiger auf nicht-statische Memberfunktionen sind keine Zeiger, und eine solche Konvertierung in integrale Werte ist für sie nicht vorgesehen.
-
Ja, ich möchte es benutzen und es handelt sich nur um statische Methoden sowie frei Funktionen, die sich ja pointermäßig nicht unterscheiden. Muss jetzt leider erstmal weg. Werde nachher noch mal schreiben, wo ich dies brauch.
-
camper schrieb:
mysterio schrieb:
Hallo,
ist das casten eines statischen Memberfunktionspointers oder eines Funktionspointers einer freien Funktion in Richtung uintXX_t und wieder in den Orginaltyp zurück Standardkonform?
Zeiger auf nicht-statische Memberfunktionen sind keine Zeiger, und eine solche Konvertierung in integrale Werte ist für sie nicht vorgesehen.
Darf man Zeiger auf nicht-statische Memberfunktionen mit memcpy() rumkopieren?
Falls ja könnte man sie ja relativ einfach in ein Byte Array kopieren.
-
hustbaer schrieb:
Darf man Zeiger auf nicht-statische Memberfunktionen mit memcpy() rumkopieren?
Falls ja könnte man sie ja relativ einfach in ein Byte Array kopieren.Gute Frage, würde mich auch mal interessieren. Wenn ich aber so darüber nachdenke: Warum eigentlich nicht. Die Frage ist halt wie man dies dann castet, um wieder auf den richtigen Typ zurück zu kommen, obwohl mir da der union-cast-Trick einfallen würde. Habe sowas aber noch nicht/nie getestet.
Ich hatte ja auch versprochen, dass ich sage, wo ich den Kram brauche. Es geht in den Betriebssystemkontext und dort um Interruptvektortabellen. In dieser Tabelle sind die Einträge einfach als uint32_t definiert, ja
leider ist dies so. Kann ich auch nicht ändern, weil Code ist nicht von mir und auch nicht in meinem Verantwortungsbereich. Ich kann da halt nur was reinschreiben. Was dort halt stehen soll sind Sprungziele. Das ganze kommt wohl ursprünglich aus der Assemblerwelt. Diese Sprungziele sind aber ähnlich einfachen Funktionen (insbesondere solche ohne Parameter). Grundvoraussetzung ist noch, das sie keinen prolog/epilog besitzen.
-
In dem Fall ist sowieso ziemlich egal was Standardkonform oder Portierbar ist.
Mach einfach einen reinterpret_cast auf uint32_t und guck was passiert.
Grundvoraussetzung ist noch, das sie keinen prolog/epilog besitzen.
Naja, die Funktionen müssen genau den Calling-Conventions oder allgemeiner den Vorgaben entsprechen, die das jeweilige OS verwendet/macht.