Virtuelle Methode Offset
-
Hi.
Ich habe mal eine Frage zu einem Offset einer virtuellen Methode einer abgeleiteten Klasse. Folgender Code:class A { public: virtual void oneUselessFunction(void); virtual bool justAnotherFunction(int iX, int iY); } class B : public A { public: virtual void iAmUseless(void); virtual int blaBlubb(bool bActive); virtual void iNeedThisFunction(void); }Zum reinen Verständnis erstmal. Der Offset der Funktion A::oneUselessFunction ist ja 0 (logisch), ist B::iAmUseless nun auch 0 oder 2?
Ich gehe davon aus, dass B::iNeedThisFunction den Offset 4 haben _müsste_.Danke für alle Antworten

Gruß
-
Funktionen haben einen Offset? Das kann, wenn überhaupt, nur dein Compiler wissen wie das gemacht wird.
Wofür musst du das denn wissen?
-
ist B::iAmUseless nun auch 0 oder 2?
0 nicht, wenn oneUselessFunction(void) den Index 0 hat.
-
Hi.
Natürlich haben virtuelle Funktionen Offsets die man problemlos benutzen kann (unter Linux sowie Windows).Gruß
-
theliquidwave schrieb:
Natürlich haben virtuelle Funktionen Offsets die man problemlos benutzen kann (unter Linux sowie Windows).
Das war mir neu. Wie greift man darauf zu?
-
theliquidwave schrieb:
Natürlich haben virtuelle Funktionen Offsets die man problemlos benutzen kann (unter Linux sowie Windows).
Offsets in Bezug worauf? Wenn du dich auf das interne Speicherlayout beziehst, das vom Compiler geplant und erzeugt wird, dann ist das völlig compilerspezifisch. Der C++-Standard legt in dem Gebiet nichts fest.
-
theliquidwave schrieb:
Natürlich haben virtuelle Funktionen Offsets die man problemlos benutzen kann (unter Linux sowie Windows).
Was ist das denn? Ein "Offset einer virtuellen Funktion"? Ich kann mit dieser Aneinanderreihung von Wörtern nicht viel anfangen. Wozu bräuchte man das?
Wenn Du von Offset sprichst, verbinde ich damit den Adressunterschied vom "Anfang" des Objektes bis zu einem bestimmten Element des Objekts. Funktionen werden da aber nicht "im Objekt gespeichert". Wie Dein Compiler das mit den virtuellen Funktionen macht, hat Dich gar nicht zu interessieren.
Gruß,
SP
-
Ich glaube er meint das das Virtual Table und deren Pointer.
-
Soweit ich weiss gibt es für eine Funktion virtual oder nicht nur eine Adresse die vom Compiler in der Symboltablle vor der Erstellung des Binaries verwendet wird. Die Position also das Offset von dem du sprichst ist nicht festgelegt, genauso wenig ob der Parser ein LL(k) LR(k), oder ein Derivat davon sein muss. Daher kannst Du zwar zur Laufzeit ein Offset ermitteln - über function pointer - aber das nicht verpflichtend und kann sich beim nächsten Kompilieren (wenn der Source geändert wurde) ändern.
-
theliquidwave schrieb:
Natürlich haben virtuelle Funktionen Offsets die man problemlos benutzen kann (unter Linux sowie Windows).
Ach du dicker Bär, was fragst du denn wenn du eh schon den vollen Durchblick hast?

Streich in deinem Satz "problemlos" und ersetze es durch "wenn man abenteuerlustig ist und keinen Wert auf Kompatibilität legt".
-
Hi.
Naja - auch wenn ich meine Frage vermutlich falsch formuliert habe - funktionieren tut es doch. Virtuelle Funktionen, dessen Offset ich bereits kenne, kann ich problemlos aufrufen. So wie DeepCopy schon richtig vermutet meine ich natürlich VMTs. Durch längeres ausprobieren habe ich herausgefunden dass meine Vermutung so stimmte. Die Offsets aus Post 1 stimmen
Danke an alle Antworten.
Gruß
-
theliquidwave schrieb:
Naja - auch wenn ich meine Frage vermutlich falsch formuliert habe - funktionieren tut es doch. Virtuelle Funktionen, dessen Offset ich bereits kenne, kann ich problemlos aufrufen. So wie DeepCopy schon richtig vermutet meine ich natürlich VMTs. Durch längeres ausprobieren habe ich herausgefunden dass meine Vermutung so stimmte. Die Offsets aus Post 1 stimmen


Ich behaupte, dass dein Problem viel viel eleganter ohne solche "low-level hacks" gelöst werden kann. Nur falls Du es noch nicht weißt: Die Implementierung von virtuellen Funktionen ist genauso wenig standardisiert wie das Layout einer Klasse.
Das, was Du da getan hast solltest Du Dir ganz schnell wieder abgewöhnen. So eine Trickserei ist meiner Meinung nach ein Entlassungsgrund. Ich würde Dich wegen Inkompetenz feuern. (Nicht persönlich nehmen. Ich wollte nur, dass wir uns richtig verstehen, wie böse das ist.)
Gruß,
SP
-
Durch längeres ausprobieren habe ich herausgefunden dass meine Vermutung so stimmte.
Und was hast du gewonnen?
-
hustbaer schrieb:
Streich in deinem Satz "problemlos" und ersetze es durch "wenn man abenteuerlustig ist und keinen Wert auf Kompatibilität legt".
Du hast "oder wenn du COM benutzen willst" vergessen.
(Auch wenn man argumentieren könnte, daß das von deinen Restriktionen bereits abgedeckt wird. :p)
-
theliquidwave schrieb:
Hi.
Naja - auch wenn ich meine Frage vermutlich falsch formuliert habe - funktionieren tut es doch. Virtuelle Funktionen, dessen Offset ich bereits kenne, kann ich problemlos aufrufen. So wie DeepCopy schon richtig vermutet meine ich natürlich VMTs. Durch längeres ausprobieren habe ich herausgefunden dass meine Vermutung so stimmte. Die Offsets aus Post 1 stimmen
Es gibt mehrere Arten das zu implementieren. Mit einem anderen Compiler, anderen Compileroptionen, einer anderen Compilerversion oder einer anderen Plattform kann sich das sofort wieder aendern

-
theliquidwave schrieb:
Hi.
Naja - auch wenn ich meine Frage vermutlich falsch formuliert habe - funktionieren tut es doch. Virtuelle Funktionen, dessen Offset ich bereits kenne, kann ich problemlos aufrufen. So wie DeepCopy schon richtig vermutet meine ich natürlich VMTs. Durch längeres ausprobieren habe ich herausgefunden dass meine Vermutung so stimmte. Die Offsets aus Post 1 stimmen
Danke an alle Antworten.
Gruß
Es gibt Compiler, die das anders machen. Zum Beispiel wird bei anderen Compilern keine vtable verwendet, sondern zuerst eine Art Wrapperfunktion aufgerufen, die dann durch $Compilermagie die richtige Funktion raus sucht.
Hier ist ein ziemlich ausführlicher Abriss darüber, wie unterschiedlich die Implementationen von Funktionszeigern, insbesondere Memberfunktionszeigern sein können: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
-
Es garantiert dir außerdem niemand, dass sich die Reihenfolge nicht ändert, wenn du neue Funktionen hinzufügst. Wenn man sich auf einen Compiler festlegt und ein Programm schreibt das diese Offsets aus dem Binary (oder aus sonst einer Datei) ermittelt ist das noch einigermaßen robust und einsatzfähig.
Aber wenn du da anfängst diese von Hand zu ermitteln wirst du keinesfalls glücklich werden.Alles was ich geschrieben habe setzt natürlich voraus, dass du ein konkretes Problem hast bei dem dies der richtige Ansatz ist. Ich vermute allerdings, dass deine Frage nur auf Neugier beruht.d
-
Ich finde den Beitrag sehr interessant.
Finde es schade, dass man in C++ diese Tabelle nicht sandardisiert.
Ein Zugriff würde das Verständnis für Funktionspointer fördern.
Gruß
-
AlexXXx schrieb:
Ein Zugriff würde das Verständnis für Funktionspointer fördern
Nee, nur mehr Hacks erlauben. Die Sprache C++ ist eine Sprache / Definition. Das sollte sowieso von der Umsetzung getrennt sein.
-
AlexXXx schrieb:
Finde es schade, dass man in C++ diese Tabelle nicht sandardisiert.
Man kann auch zu viel standardisieren und es später bereuen. In diesem Fall würde das den Standard einfach nur länger machen, ohne dass man dabei etwas gewinnt.