Ich bin verwirrt über die Verwendung des register
Schlüsselworts in C. Es wird allgemein gesagt, dass seine Verwendung nicht erforderlich ist, wie in dieser Frage zum Stapelüberlauf .
Ist dieses Schlüsselwort in C aufgrund moderner Compiler vollständig redundant oder gibt es Situationen, in denen es noch nützlich sein kann? Wenn ja, in welchen Situationen ist die Verwendung von register
Schlüsselwörtern tatsächlich hilfreich?
const
Keyword, aber diese Frage bewies, dass ich falsch lag. Also werde ich abwarten und sehen, was ich bekomme.const
Schlüsselwort ist etwas anderes als registrieren.Antworten:
Es ist sprachlich nicht redundant, es ist nur so, dass Sie dem Compiler mitteilen, dass Sie es "vorziehen" würden, eine Variable im Register zu speichern. Es gibt jedoch absolut keine Garantie dafür, dass dies tatsächlich zur Laufzeit geschieht.
quelle
Wie bereits erwähnt, machen Compiler-Optimierer das
register
Schlüsselwort für andere Zwecke als das Verhindern von Aliasing im Wesentlichen überflüssig. Es gibt jedoch ganze Codebasen, die bei deaktivierter Optimierung kompiliert werden (-O0
in gcc-speak ). Für einen solchen Code kann dasregister
Schlüsselwort eine große Wirkung haben. Insbesondere Variablen , die ansonsten einen Schlitz auf dem Stapel erhalten würden (dh alle Funktionsparameter und automatische Variablen) kann direkt in ein Register gesetzt werden , wenn mit dem erklärtenregister
Schlüsselwort.Hier ein Beispiel aus der Praxis: Nehmen Sie an, dass ein Datenbankabruf stattgefunden hat und dass der Abrufcode das abgerufene Tupel in eine C-Struktur gestopft hat. Angenommen, eine Teilmenge dieser C-Struktur muss in eine andere Struktur kopiert werden. Möglicherweise handelt es sich bei dieser zweiten Struktur um einen Cache-Datensatz, der die in der Datenbank gespeicherten Metadaten darstellt, die aufgrund von Speicherbeschränkungen nur eine Teilmenge jedes Metadatensatzes als gespeichert zwischenspeichern in der Datenbank.
Bei einer Funktion, die einen Zeiger auf jeden Strukturtyp verwendet und deren einzige Aufgabe es ist, einige Elemente von der ursprünglichen Struktur in die zweite Struktur zu kopieren: Die Strukturzeigervariablen befinden sich auf dem Stapel. Wenn Zuweisungen von den Mitgliedern einer Struktur zu den Mitgliedern der anderen Struktur erfolgen, werden die Adressen der Struktur für jede Zuweisung in ein Register geladen, um den Zugriff auf die Mitglieder der Struktur durchzuführen, die kopiert werden. Wenn die Strukturzeiger mit dem
register
Schlüsselwort deklariert würden, würden die Adressen der Strukturen in den Registern verbleiben, wodurch die Anweisungen zum Laden der Adresse in das Register für jede Zuweisung effektiv herausgeschnitten würden.Denken Sie auch hier daran, dass die obige Beschreibung für nicht optimierten Code gilt.
quelle
Grundsätzlich teilen Sie dem Compiler mit, dass Sie die Adresse der Variablen nicht übernehmen und der Compiler dann angeblich weitere Optimierungen vornehmen kann. Soweit ich weiß, können moderne Compiler ziemlich gut bestimmen, ob eine Variable in einem Register gespeichert werden kann / sollte oder nicht.
Beispiel:
quelle
In den 16-Bit-Computertagen benötigte man oft mehrere Register, um 32-Bit-Multiplikationen und -Divisionen auszuführen. Da Gleitkommaeinheiten in Chips eingebaut wurden und dann 64-Bit-Architekturen "übernahmen", erweiterten sich sowohl die Breite der Register als auch deren Anzahl. Dies führt schließlich zu einer vollständigen Neuarchitektur der CPU. Siehe Dateien auf Wikipedia registrieren .
Kurz gesagt, es würde einige Zeit dauern, um herauszufinden, was tatsächlich vor sich geht, wenn Sie sich auf einem 64-Bit-X86- oder ARM-Chip befinden. Wenn Sie sich auf einer eingebetteten 16-Bit-CPU befinden, erhalten Sie möglicherweise tatsächlich etwas. Die meisten kleinen eingebetteten Chips laufen jedoch nicht zeitkritisch - Ihr Mikrowellenherd tastet möglicherweise 10.000 Mal pro Sekunde Ihr Touchpad ab - nichts, was eine 4-MHz-CPU belastet.
quelle
Um festzustellen, ob das Schlüsselwort register eine Bedeutung hat, reichen winzige Beispielcodes nicht aus. Hier ist ein C-Code, der mir vorschlägt, dass das Schlüsselwort register immer noch eine Bedeutung hat. Aber es könnte bei GCC unter Linux anders sein, ich weiß es nicht. Wird das Register int k & l in einem CPU-Register gespeichert oder nicht? Linux-Benutzer sollten (insbesondere) mit GCC und Optimierung kompilieren. Bei Borland bcc32 scheint das Schlüsselwort register zu funktionieren (in diesem Beispiel), da der & -operator Fehlercodes für deklarierte Ganzzahlen des Registers angibt. HINWEIS! Dies ist bei einem winzigen Beispiel mit Borland unter Windows NICHT der Fall! Um wirklich zu sehen, was der Compiler optimiert oder nicht, muss es ein mehr als winziges Beispiel sein. Leere Schleifen reichen nicht aus! Trotzdem - WENN eine Adresse mit dem & -operator gelesen werden kann, wird die Variable nicht in einem CPU-Register gespeichert. Aber wenn eine vom Register deklarierte Variable nicht gelesen werden kann (was beim Kompilieren zu Fehlercode führt) - muss ich davon ausgehen, dass das Schlüsselwort register die Variable tatsächlich in ein CPU-Register einfügt. Es kann auf verschiedenen Plattformen unterschiedlich sein, ich weiß es nicht. (Wenn es funktioniert, ist die Anzahl der "Ticks" mit der Registerdeklaration weitaus geringer.
quelle