Adresse der register-Variablen in C und C++
Ich weiß, das Konzept des register-variable und es Anwendungsfälle, aber es gibt einige Fragen in meinem Kopf auf, was ich ausprobiert habe.
-
Ich kann nicht auf die Adresse der register-Variablen in C kann ich zwar tun Sie es C++! Warum? Gibt es irgendein Problem beim Zugriff auf die Adressierung des register-variable?
-
Nehme an, wenn ich deklarieren Sie eine string-variable in C++ als registrieren, dann wo wird diese variable gespeichert werden? Was ist der Punkt in der Deklaration der storage-Klasse von nicht-numerischen Datentypen wie "string" in C++ zu registrieren??
UPDATE:
Ich dachte, dass C++ erlaubt es uns zu Holen, die Adresse der register-Variablen, da war ich nicht immer alle Fehler in meinem Programm ist wie folgt:
#include<iostream>
#include<time.h>
using namespace std;
clock_t beg, en;
int main(){
int j, k=0;
beg=clock();
for(register int i=0;i<10000000;i++){
/*if(k==0){
cout<<&i<<endl; //if this code is uncommented, then C++ rejects the recommendation to make 'i' as register
k++;
}*/
}
en=clock();
cout<<en-beg<<endl;
cout<<&j<<endl<<&k;
return 0;
}
Was ich beobachtet habe ist, wenn ich die variable 'i' als registrieren und versuchen Sie nicht, drucken Sie die Adresse mit '&' ich mir dann C++ akzeptiert die Empfehlung und speichert 'ich' im register, dieses kann geschlossen werden aus der Laufzeit der for-Schleife, die immer um 4-12 ms, wenn 'ich' ist im register. Aber wenn ich versuchen zu drucken, die Adresse der variable 'i' dann, obwohl ich nicht keine Fehler bekommen aber C++ lehnt die Empfehlung und dieser kann geschlossen werden ab dem Zeitpunkt der Ausführung der Schleife, die sich immer mehr als 25, wenn ich mich nicht registrieren!!
So, im Grunde kann ich nicht abrufen Adresse einer Variablen mit storage class als register sowohl in C als auch C++!! WARUM?
- Register-Variablen haben keine Adressen.
- U sagen, es gibt keine Adresse ein register? Wie kommen computer weiß dann, in welchem register die variable 'i' wird gespeichert?
- "Ich weiß, dass das Konzept des register-variable". NEIN, DU NICHT!!!
- Dann lassen Sie es mich bitte wissen! Bitte korrigieren Sie mich.
- keine anderen Kommentare und die Antwort haben bedeckt es.
- Der Speicherort von
i
ist bestimmt durch den compiler, die es in einem register oder auf den stack. Der computer oder die CPU nicht "weiß" nichts-es läuft nur der binäre code, der vom compiler erzeugt. - Im Allgemeinen ein register, eine register-Nummer, die in der Art einer Adresse. Jedoch, wieder im Allgemeinen, verschiedene Maschinen-Anweisungen werden verwendet, um die Adresse eines Registers als Adresse an den Speicher.
- Betrachten Sie die Montage, wo die Register-und Speicher-Adressen sind sehr unterschiedlich. Betrachten wir nun, dass der compiler wandelt den code in assembly.
- mögliche Duplikate von Adresse der register-Variablen Hat eine gute Beschreibung, warum es funktioniert in C++.
- So registriert haben keine Adressen? Sie verwiesen wird, die Namen sagt A, B, C..? und somit kein Punkt zu Holen Adresse einer variable gespeichert im register? Ist es?
- Funktioniert es wirklich in C++?? Haben Sie gelesen oder ausprobiert, was ich geschrieben in meiner Frage?
- Auf x86 -, register Verweise sind hardcoded in den Maschinen-code Anweisungen.
- registriert haben Namen. auf x86 -, Sie verwiesen als eax, ebx, ecx etc. in der Montage mnemonischen Befehle. In x64, Sie sind rax, rbx, rcx usw.
- OK! Das ist cool! Und was ist mit nicht-numerischen Datentypen wie "string" in C++? Wohin gehen Sie, wenn angegeben, wie registrieren?
- "Adresse" in diesem Kontext bedeutet "Ort im virtuellen Speicher". So kann man nicht auf die Adresse eines Registers, eine Datei auf der Festplatte, eine Banane, oder deine Mutter-in-law ' s Hund, denn Sie befinden sich nicht im virtuellen Speicher.
- Ein
std::string
Objekt in der Regel nicht passen in ein register, so der Hinweis ignoriert werden. Sollten Sie einfach vergessen, über dieregister
Schlüsselwort, einschalten der compiler-Optimierungen, und lassen Sie den compiler ausführen, diese Mikro-Optimierungen. - Ya string passt nicht in ein register. So what? Die Anfrage wird ignoriert, sofort? Wie etwa der Speicherung im cache?
- Der compiler in der Regel nicht machen, Entscheidungen über was zu speichern im cache, da der Prozessor tut es in der hardware. (Das ist nicht zu sagen, Sie kann es nicht, aber auf den meisten Architekturen alles Sie Zugang erhalten, die im cache gespeichert, es sei denn, Sie verwenden spezielle Anweisungen, die bypass-cache).
- Nein, mein Motiv ist nicht, dass...
- Ihr Verhalten ist.
- Versuchen Sie, die Codierung etwas in der Montage. Es wird Ihnen helfen zu verstehen, die Idee von Registern vs Speicher.
- oder noch besser: füttern Sie Ihre Beispiel-Programm für den compiler und es erzeugt eine Liste der assembly.
- Vielen Dank an alle für Eure Hilfe und ich entschuldige mich für mein Verhalten... Sie Menschen sind wirklich genial.
Du musst angemeldet sein, um einen Kommentar abzugeben.
C und C++ sind unterschiedliche Sprachen.
In C, können Sie nicht die Adresse einer Variablen mit
register
Speicher. Vgl. C11 6.7.1/6:In C++
register
ist eine veraltete, sinnlose keyword, das hat keinen Effekt (außer vielleicht dienen, da ein compiler-hint), und Variablen, die alsregister
nur noch die automatische Speicherung. Insbesondere C++ nicht ein "register" Speicher-Klasse. (Es muss nur die Speicher-Klasse Planer, geerbt von C.) Cf. C++11, 7.1.1/3:Sogar in C nichts ist wirklich garantiert, darüber, wie register, Speicher implementiert ist (Implementierungen sind frei zu behandeln
register
alsauto
), aber die Sprache, die Regeln gelten unabhängig.g++ -O3
, und beide Versionen produzieren identischen code. (Obwohl es einen Unterschied gibt bei -O0. Aber was gut ist, sprechen C++ ohne Optimierungen. Denkenregister
als eine lokalisierte compiler-pragma wenn man so will.)Erste, lassen Sie uns einen Blick auf die einschlägigen Normen. Es ist immer möglich, dass C und C++ haben unterschiedliche Bedeutungen für dieses keyword.
C++ 2011 Abschnitt 7.1.1 Absätze 2 und 3:
C 2011 Abschnitt 6.7.1, Absatz 6 und Fußnote 121:
Also, lasst uns mitnehmen, was wir hier gelernt haben.
Als zu dem, was Sie sehen in der Praxis:
register int
, so lassen Sie uns verschieben Vergangenheit.register
. In diesem Fall wäre es gut, zu zeigen, Ihren test, weil es vielleicht Probleme in der test selbst. Wenn der vollständige test ist in Ordnung, dann ist es sicherlich möglich, dass dein compiler ist mit dem Hinweis zu produzieren besseren code.for (int i=0; i<100; ++i){}
undfor (register int i=0; i<100; ++i) {}
.Unter der Adresse einer Variablen erzwingt der compiler, um es zu speichern in einem Speicher (es sei denn, es ist eine Architektur, wo-Register hat eine Adresse - ich denke die TI 9900-Serie-Prozessoren implementiert wurden, auf diese Weise, aber es ist eine vage Erinnerung von ca 1984). Wenn Sie gesagt haben, die compiler verwenden eine
register
macht, dass es nicht kompatibel. Obwohl der C++ - standard zu suggerieren scheint, dass der compiler nicht verpflichtet, Ihnen zu sagen, so, und kann in der Tat ignorieren dieregister
Schlüsselwort.C++11-Entwurf n3337, Abschnitt 7.1.1, Punkt 3
(Edit: ja, der TMS 9900 hat in der Tat "- Register in memory", also theoretisch, Sie können die Adresse eines Registers, in das Architektur - aber die Architektur ist viel mehr, dass "registriert, live im Speicher (der Adresse)" als "- Register haben Adressen").
Die grundlegende Antwort ist, dass auf den meisten Architekturen, general purpose Register, nicht Speicher-Adressen. Im Allgemeinen wird ein Zeiger einfach ein (virtueller) Speicher Adresse des Speicherplatzes mit dem Objekt. Dies geschieht auf die Effizienz.
Wäre es möglich, erweitern das Konzept der Zeiger auf Punkt-zu-Speicher-oder register. Allerdings würde dies verringert die Geschwindigkeit des Programms, wie der code zu dereferenzieren einen Zeiger benötigen würde, um zu überprüfen, welche Art von Ort ist als Zeiger auf.
Viele Aspekte von C stammen aus einem Wunsch ermöglicht single-pass-Zusammenstellung. Viele der frühen Compiler würde das Lesen ein wenig Quellcode, erzeugen eine Baugruppe oder Maschine code, vergessen die meisten, was Sie gerade Lesen, Lesen Sie ein wenig mehr code, generieren einige weitere Montage - /Maschinen-code, etc. Wenn der compiler erzeugt Maschinencode, der kann es brauchen, um zu bauen, eine Liste von back-patches für Dinge wie vorwärts springt, aber ein compiler könnte generieren von code für die Funktionen, die größer waren als der verfügbare RAM.
Viele Maschinen haben ein paar Register, die könnten sich mit der Speicherung der Werte, aber ein compiler nicht in der Lage wäre zu wissen, was Variablen sein könnten sinnvoll gehalten, in einem Register zu einem bestimmten Punkt im code, es sei denn, es weiß, wie die Variablen werden später im code. Etwas wie:
single-pass-compiler hat keine Möglichkeit zu wissen, ob es könnte sicher zu halten
j
in ein register über den Zugang zu*p
. Spülungj
auf dem Speicher, bevor die*p+=10;
- und wiederverladens es nach auffressen würde die meisten der Vorteil der Zuweisung von einem register an, aber ein compiler übersprungen Spülen und neu zu laden aber der obige code, gefolgt vonp=&j;
es hätte ein problem. Alle schleifendurchläufe nach der ersten würde müssen haltenj
im Speicher während der Ausführung*p+=10;
, aber der compiler würde schon vergessen haben den code, der erforderlich wäre, damit für den zweiten Durchgang.Dieses Problem wurde gelöst, indem Sie angeben, dass wenn ein compiler deklariert ist
register
compiler kann sicher code generieren, der davon ausgeht, dass keine Zeiger-basierte Zugriffe auswirken. Das Verbot gegen die Aufnahme der Adresse war IMHO unnötig over-reaching ( * ), aber es war einfacher zu beschreiben, als eine, die es erlauben würde, die qualifier werden in mehr Umstände.(*)Die Semantik wäre nützlich, auch heute noch, wenn
register
versprochen, dass ein compiler könnte sicher halten Sie eine variable in ein register, wenn es geleert es zu Speicher, wenn Sie deren Adresse genommen wurde, und statt off auf neu laden, bis das nächste mal der code verwendet die variable, verzweigten rückwärts [über Schleifenkonstrukt oder goto], oder trat in eine Schleife, wo die variable verwendet wurde].Gerade weil es ein register. Eine Adresse ist eine Adresse, die von einem Speicherort. Wenn etwas ist, die Ihren Wohnsitz in einem register ist es per definition nicht im Hauptspeicher.
i
in der Ausgabe. Es ist nur ein Haufen von Montage-Befehle und Speicheradressen. Es ist der compiler erzeugt die Anweisungen der Durchführung der Operationen aufi
.In C, können wir die Adresse einer variable mit dem register Speicher. wir speichern mit normalen Variablen-Namen.