2016-07-13 8 views
4

Ich habe eine Menge Zeit damit verbracht, TOC- und Compiler-Design zu studieren, noch nicht fertig, aber ich fühle mich mit den Konzepten wohl. Auf der anderen Seite habe ich ein sehr oberflächliches Wissen über Assembler- und Maschinencode, und ich habe immer den Wunsch/die Notwendigkeit, die beiden Seiten (HLL- und LLL-Darstellung des Codes) zu verbinden, da ich C++ mit großer Aufmerksamkeit lerne Leistungs- und Optimierungsgespräche.Sind Variablenbezeichner am Ende des Tages völlig überflüssig?

C++ ist eine statisch typisierte Sprache:

Meine Frage ist: Unsere Variablen, wenn sie als Ausdrücke in den Aussagen des Codes geschrieben, tun all diese Variablen (und andere Organisationen, die mit Kennungen) zur Laufzeit werden, nur Anweisungen von Adressierung auf Positionen des virtuellen Speichers (für statisch und für global) und Adressierung relevant für Stack-Adresse für lokale Variablen?

Ich meine, nach einer erfolgreichen Kompilierung einschließlich semantischer und syntaktischer Verifikation, ist es nicht klug, Daten zur Laufzeit als garantierte Entitäten von Zielspeicherbytes zu behandeln, ohne irgendeinen Bezeichner oder irgendeine Überprüfung zu denken, mit der Symboltabelle nicht mehr erforderlich?

Wenn meine Frage die Art von Fragen zu sein scheint, die auf mangelnden Lernaufwand zurückzuführen sind (was ich nicht hoffe), bitte informieren Sie mich darüber und sagen Sie mir, wo ich lesen soll. Wenn das der Fall ist, dann ist es ehrlich gesagt, weil ich mich heute auf C++ konzentriere und noch nicht die Möglichkeit habe, fundierte Kenntnisse von Low-Level-Sprachen zu haben, dafür entschuldige ich mich im Voraus.

+4

Das ist im Grunde wie statisch kompilierte Sprachen ohne Introspektion oder Reflexion funktioniert.Wenn Sie eine C++ - Quelldatei kompilieren, hat die vom Compiler generierte Objektdatei keinen Verweis auf die Variablen in der Quelle. Es sind alle Speicherplätze. –

+2

Ja, Ihr Verständnis ist richtig. –

+0

TLDR; und verwirrend. Aber 'C++ ist eine statisch typisierte Sprache:' ist falsch. Es enthält C. –

Antwort

2

Ja, meistens. Es gibt ein paar Details, die dazu führen, dass Bezeichner mehr als nur Adressen oder Stapeloffsets bleiben.

Zuerst haben wir in RTTI in C++, was bedeutet, dass während der Laufzeit der Name von mindestens Typen noch verfügbar sein kann. Zum Beispiel:

const std::type_info &info = typeid(*ptr_interface); 
std::cout << info.name() << std::endl; 

würde den Namen drucken wie auch immer geartete *ptr_interface ist.

Zweitens können aufgrund der Art und Weise, wie ein Programm verknüpft wird, die Symbole aus den Objektdateien noch im ausführenden Bild vorhanden sein. Sie haben zum Beispiel den Linux-Kernel, der dies verwendet, da er eine Rückverfolgung des Stapels einschließlich der Funktionsnamen erzeugen kann. Außerdem verwendet es die Kenntnis von Funktionsnamen, um Module laden und verknüpfen zu können. Eine ähnliche Funktionalität existiert in der Gnu C-Bibliothek, als wenn sie dafür verknüpft ist, Funktionsnamen in Stack-Traces abzurufen.

In normalen Fällen wird der Code nicht von den ursprünglichen Namen der Variablen beeinflusst (aber der Compiler wird natürlich Code ausgeben, der für den Typ der Variablen geeignet ist).

+0

Vielen Dank für die Klarstellung. Ich denke für, sagen wir, einfache Variablen, die auf l-Wert oder r-Wert im gewöhnlichen Code zugreifen x = y + 1; Die Variable, auf die der Ausdruck zugreift, wird als eine Anweisung der Adressierung zur Laufzeit weder für den Bezeichner noch für den Typ aktiviert. Ist es richtig, dies anzunehmen? – Physician

+1

Beachten Sie, dass RTTI eine Funktion ist, die vom Compiler ein- und ausgeschaltet werden kann und zusätzlichen Aufwand für das Programm verursacht. – NathanOliver

+1

@Physician gut, der Maschinencode selbst wird entsprechend breite Register/Alignment verwenden, um auf den Speicher zuzugreifen, der für die Variable reserviert ist, aber es kümmert nicht von Haus aus, wie der C++ Code aussah, wenn das letztendlich deine Frage ist. und es ist sicherlich egal, welche Variablen benannt wurden. –

3

Sie sind genau richtig. Nach der Kompilierung zu Maschinencode gibt es keine Vorstellung mehr von einem Variablenbezeichner (oder von einem Variablentyp). Es sind nur Bytes an einem bestimmten Ort. Welcher Speicherort wurde vom Compiler (beim Kompilieren) basierend auf dem Variablennamen oder vom Linker (beim Verknüpfen) im Fall globaler Variablen bestimmt.

Natürlich kann es nützlich sein, Informationen wie Identifikatoren für Debugging-Zwecke zu behalten. Genau dies bedeutet "Kompilieren mit Debug-Informationen": Wenn Sie das tun, wird der Compiler die (redundanten) Bezeichner irgendwie in den generierten Code einbetten, so dass ein Debugger auf sie zugreifen kann. Oder legen Sie sie in eine separate Datei neben; Die Einzelheiten hängen vom Format der Debugging-Informationen ab.

Verwandte Themen