2012-08-09 22 views
25

Ich debugging einige C++ - Code in GDB und ich fand heraus, dass einige Aufrufe einen sogenannten "synthetischen Zeiger" verwenden. Das Herumgucken ergab kein sinnvolles Ergebnis. Wenn Sie hier auf SO suchen, beziehen sich die meisten Fragen mit "synthetisch" in ihrem Titel auf ein Java-Feature (auch wenn sie mir vorwerfen, dass "synthetisch" in diesem Zusammenhang "etwas künstlich vom Compiler erzeugtes" bedeuten könnte).Was ist ein synthetischer Zeiger?

Eg, schauen Sie sich diese Backtrace, nahm von einem Betrieb, in dem Konstruktor von MyClass ausgeführt, über ein Klassenmitglied m genannt (dieser Code ist mit -O2 zusammengestellt):

#0 MyClass (arg=..., this=<synthetic pointer>) at somefile.h:144 
144  m->lock(); 
gdb$ print this 
$1 = (MyClass * const) <synthetic pointer> 
gdb$ print *this 
$2 = <optimized out> 

Der Stack-Trace oben gibt eindeutig an, dass this ein Zeiger auf ein Objekt ist, das optimiert wurde, aber wie ist es möglich, dass eine Methode (dh ihr Konstruktor) darauf aufgerufen wurde? Meine wilde Vermutung ist, dass, selbst wenn das eingeschlossene Objekt (m) im Code aktiv verwendet wird, einige Optimierungen den Compiler entscheiden lassen, dass das umschließende Objekt (this) nicht wirklich notwendig ist. Da der Methodenaufruf m->lock(), der nicht optimiert werden kann, irgendwo ausgegeben werden muss, erzeugt der Compiler ein "gefälschtes" (synthetisches?) Objekt, das nirgendwo im Speicher liegt, nur um es zu wickeln m.

Ich habe keine starke Compiler-Erfahrung, also weiß ich nicht, ob diese Schlussfolgerung wirklich Sinn macht. Könnte jemand bitte etwas Licht dazu bringen?

Vielen Dank.

Antwort

12

Ein Compiler kann feststellen, ob this tatsächlich dereferenziert ist (d. H. Mit den spezifischen CPU-Details, nicht mit den allgemeinen C++ - Regeln). Wenn eine Methode this nicht wirklich dereferenziert, muss keine physische Repräsentation verfügbar sein.

[bearbeiten] In den Kommentaren erwähnt jww einen anderen Fall. Ein Singleton hat nur eine Kopie, daher kann ein intelligenter Compiler seine Member als Globals behandeln. Das heißt, die Adresse singleton->foo ist nur die Konstante &singleton + offset(foo). Als Ergebnis dieser Optimierung müssen die Singleton-Methoden die Adresse this nicht wirklich dereferenzieren, um Zugriff auf die Singleton-Mitglieder zu erhalten, so dass sie erneut optimiert werden können.

+0

Ja, mein 'MyClass' Objekt wurde erstellt, nie referenziert und einige Zeit später zerstört; Die einzigen wichtigen Operationen waren die Nebeneffekte des Konstruktors/Destruktors (für den Datensatz ist es eine benutzerdefinierte Implementierung einer Bereichssperre). Das muss also so sein. Vielen Dank. –

+2

Ist das tatsächlich ein synthetischer Zeiger (wenn "das" optimiert ist)? Ich denke, dass diese Antwort als eine Randnotiz interpretiert werden kann, dass ja ein Objekt optimiert werden kann, wenn es nie referenziert wird, aber nicht, dass der "synthetische Zeiger" der Fall ist, wenn "dieses" optimiert ist. Ich sehe synthetischen Zeiger in Stack-Traces und ich bin mir nicht sicher, wie man das interpretiert, es ist nicht die reguläre Nachricht. –

+2

@JoeyCarson: Es ist alles ein bisschen philosophisch. Formal existieren entweder Objekte oder sie nicht. Nachdem ein Optimierer ausgeführt wurde, können Objekte teilweise vorhanden sein, bis zu dem Grad, der für das beobachtbare Verhaltensprogramm erforderlich ist. Es liegt am Debugger, reale Objekte zu fälschen, und das ist keine Wissenschaft. – MSalters