Frage

In C, können wir nicht verwenden und die Adresse eines Registervariable, um herauszufinden, aber in C ++ wir das gleiche tun können. Warum ist es legal in C ++, aber nicht in C? Kann jemand bitte dieses Konzept im Detail erklären.

War es hilfreich?

Lösung

Hier ist ein Auszug aus Abschnitt 6.7.1 (Fußnote 101) der C99-Standard (pdf) :

  

Die Implementierung kann jede register Erklärung einfach als auto Erklärung behandeln. jedoch, ob oder nicht adressierbare Speicher tatsächlich verwendet wird, wird die Adresse eines Teils eines Objekts mit Speicherklassen Spezifizierer Register deklariert sind, können nicht berechnet werden, entweder explizit (durch die Verwendung des unären & Operator wie diskutiert in 6.5.3.2) oder implizit (durch ein Feld Namen auf einen Zeiger Umwandlung, wie in 6.3.2.1 beschrieben). Somit ist der einzige Betreiber, der auf ein Array angewendet werden kann mit Speicherklassen-Bezeichner register deklariert ist sizeof.

Und von Abschnitt 7.1.1, Absatz 3 des C ++ Standard (pdf) :

  

Ein register Spezifizierer die gleiche Semantik als auto Spezifizierer zusammen mit einem Hinweis auf die Implementierung, die das Objekt so wird stark genutzt deklariert werden. [Anmerkung: der Hinweis ignoriert und in den meisten Implementierungen werden kann, wird es ignoriert, wenn die Adresse des Objekts aufgenommen wird. -Ende note]

Spaß Leckerbissen über register

Die C ++ Gruppe (WG21) will deprecate register :

  

Das register Schlüsselwort dient nur sehr wenig Funktion, nicht mehr als ein Hinweis bietet, dass eine Notiz sagt die Regel ignoriert. Es sollte in dieser Version des Standard veraltet, die reservierten Namen für die Verwendung in einem zukünftigen Standard bis zu befreien, so wie auto dieses Mal wiederverwendet wurde in ähnlicher Weise nutzlos.

     

Notizen vom März 2009 Sitzung:

     

Der Konsens der CWG war für register ironisch.

Sehen Sie, was die C99-Gruppe (WG14) sagte über register (pdf) bei einem Treffen:

  

Allgemeine Vereinbarung des „auto“ Stichwort deprecate. Sollten wir fragen WG21, um wieder auf   die bisherige Verwendung von „register“ (keine Adresse)? Nein, das wird nicht mit WG21 fliegen.

Andere Tipps

Das Register Schlüsselwort ist ein Hinweis nur und kann ignoriert werden. Die meisten C ++ Compiler ignorieren sie die ganze Zeit, aber jeder C ++ Compiler wird es ignorieren, wenn Sie die Adresse der Variablen nehmen, oder einen Verweis darauf erstellen.

Auf der anderen Seite, ein C ++ Compiler nicht wird „Register“ zu ignorieren, nur weil Sie die Adresse der Variable nehmen. Theoretisch könnte der Compiler speichert sie in einem Register und gibt Ihnen etwas Magie Zeigerwert, der irgendwie in das Register hinter den Kulissen abgebildet wird, aber das würde eine Menge Arbeit für sehr wenig Gewinn sein, also kein Compiler (die ich kenne) tut so etwas.

Da das Register ist ignorable in C als auch, ich vermute, dass das explizite Verbot gegen Adressen von Registervariablen nehmen einfach C-Compiler von der Last der Überprüfung für diese zu lindern war.

Der relevante Teil des C ++ Standard ist 7.1.1.3:

  

Eine Registerkennung hat die gleiche Semantik wie ein Auto-Spezifizierer zusammen mit einem Hinweis auf die Umsetzung, dass das Objekt so wird stark genutzt deklariert werden. [Anmerkung: der Hinweis ignoriert, und es wird, wenn die Adresse in den meisten Implementierungen werden kann des Objekts ignoriert genommen wird. -Ende note]

Sorry über die Super spät Antwort.

Das Problem ist, dass in C, register ursprünglich Werte in einem Register zu speichern gemeint, weshalb nur int und char können dafür verwendet werden. Aber mit der Zeit und vor allem Standard-C ++, erweiterte es um „schnellen Zugriff“ und nicht „im Register der CPU“. So in C ++, ein Array vielleicht einen register Typ, aber wir wissen, dass es nicht möglich ist, Arrays in einem CPU-Registern zu speichern. Daher ist es logisch in Ordnung ist, ein C ++ Adresse (im obigen Sinne) zu registrieren, aber immer noch keinen Sinn machen, wenn die Werte tatsächlich in einem CPU-Registern sind.

Ich gehe davon aus, dass das Schlüsselwort nicht einmal in die Sprache gemacht hätte, wenn es nicht für C Kompatibilität ist. Während ich nicht mit Autorität sprechen kann, wenn dies so ist, scheint es mir dort ein praktischer Grund ist es für rechtmäßig über nur ein herkömmliche erzwungene „der Compiler ist intelligenter als Sie“ -Klausel: C ++ nehmen Adressen der Dinge ohne Erlaubnis leichter als C der Fall ist. Im einzelnen Teilnehmer-Funktionen, und Referenzen.

Da Elementfunktionen einen impliziten this Parameter erfordern, wäre es unmöglich, sie von einem Objekt zu nennen erklärt register. In C gibt es nichts, was man zu sagen register struct X x; untersagt sind, solche Sprache würde in C erlaubt werden müssen ++ [da C-Kompatibilität ist der ganze Grund das Schlüsselwort existiert sogar]. Aber wenn Sie Elementfunktionen sowie unter Adressen verbieten Aufruf, das gilt auch für die anfängliche Konstruktoraufruf. Im Wesentlichen würde es nicht auf nicht-POD-Typen arbeiten. Damit Sie am Ende mit einem Speicherklasse-Bezeichner, die für eine kleine Teilmenge der Rechtstypen ist nur gültig, wenn der Rest für alles verwendet werden kann.

Sie können auch keine Verweise auf solche Objekte erstellen, auch wenn technisch nicht der Compiler muss nicht Referenzen als Zeiger behandeln. register int i; int& x; ist nicht für zwei Variablen haben, Platzbedarf, aber wenn Sie später tun &x Sie mit einem Zeiger am Ende i. So ist die anfängliche Konstrukt muss illegal gemacht werden. Während dies wie eine nicht-Frage scheint, da Referenzen in C existieren nicht ohnehin in unseren vorherigen Punkt zurückkehrt, POD-Typen mit dem register Spezifizierer deklariert nicht mehr kopiert werden kann. Der Compiler bereitgestellten Copykonstruktor ist von der Form oder X::X(const X&) X::X(X&) als angemessen.

Also, um C-Kompatibilität zu erhalten, müssen sie in register einzigartig als Speicherklassen-Bezeichner, dass es für alle Arten nicht gilt, und mindestens zwei verschiedene Teile der Norm an anderer Stelle ändern [angeben, dass Sie nicht erstellen] um die Referenzen für POD Kopieren einen Verweis auf eine Variable mit dem register Spezifizierer deklariert, und irgendwie zu arbeiten. Oder sie könnten einfach sagen, „es ist okay, die Adresse zu nehmen“ und lassen Sie Compiler entscheiden, ob die Anfragen zu ehren. Etwas, das sie wurden sowieso auf dem Tun der Planung.

Eine Registervariable keine Adresse hat, ist es gehalten hat (zumindest es soll gehalten werden) in einem CPU-Register. Da das Register Modifikator nichts anderes als ein Hinweis ist, wenn Sie die Compiler zwingen, Code zu generieren zu extrahieren Adresse ist, wird der Modifikator ignoriert, und Sie werden mit einer regelmäßigen Variable im Speicher gehalten enden.

direkt Um Ihre Frage zu beantworten, je nachdem, was man lässt Sie eine Registervariable Adresse (Ihre ursprünglichen Post widerspricht sich selbst ..) können Sie Ihre eigenen Hinweis ignorieren und sollte zumindest eine Warnung ausgeben. IMO die korrekte Umsetzung wäre die Adresse eines Registers Variable nicht zulassen nehmen.

Die wichtige Sache zu erinnern ist, dass „Register“ ist nur ein Hinweis an die Compiler (ein sinnlosen noch dazu, ich habe nie eine Geschwindigkeitsverbesserung gesehen, und die meisten Compiler wahrscheinlich einfach ignorieren). C und C ++ sind beide erlaubt Ihre „Beratung“ und halten Sie die Variable im Speicher zu ignorieren. Natürlich, wenn Sie die Adresse der Variablen nehmen, wird es zwingen, einen Platz im Speicher zuzuweisen.

C und C ++ haben nur verschiedene Regeln darüber, was Sie tun können, weil sie verschiedene Sprachen sind. Die C ++ Designer entschieden, damit Sie die Adresse eines Registers Variable erhalten, weil er nichts schaden; C ermöglicht es Ihnen nicht, es zu tun, weil sie es in den Speicher zwingen würde.

über sie denken mehr, Einschränkung C ist wohl aus dem gleichen Grund, dass Variablen, die am Anfang des Blocks-Compiler deklariert werden mussten den Speicher für Variablen Layout kann, wie es sie trifft, ohne Rücksicht darauf, wie es verwendet wird später in die Funktion.

Das ist eine Vermutung nur, aber ich bezweifle, dass Sie die Adresse eines Registers in C ++ nehmen können, weil eine solche denkt einfach nicht existieren. C ++ ist wahrscheinlich kein Register in Ihrem speziellen Fall verwenden. Beachten Sie, dass die Storage-Klasse, Qualifier register ist nur ein Hinweis an den Compiler (und die meisten, wenn nicht alle modernen Compiler es gerne ignorieren vollständig).

C und C ++ sind zwei verschiedene Sprachen, mit einer großen gemeinsamen Teilmenge. Deshalb sind einige Dinge anders zwischen ihnen.

Während ich Ihre Frage nicht verstehen, register ist (zumindest in C ++) einen Hinweis darauf, dass eine Variable könnte häufiger zugegriffen werden, und nichts mehr. In C, bedeutet dies, Sie nicht die Adresse mit dem & unärer Operator nehmen, die eine bestimmte Menge an Sinne zu der Zeit gemacht. In den frühen Tagen des C wurde erwartet, dass der Compiler nicht die Zuweisung Speicher für die Variable stören könnte, und so würde es nicht unbedingt eine Adresse sein zu nehmen.

(Computer normalerweise Register haben, die Schnellzugriffs Teile der CPU sind und somit die schnellste Speicher zugänglich. Eine Variable in einem Register leben könnten, anstatt im Speicher, wenn dies eine bessere Leistung verursacht wird.)

Heutzutage fast alle Compiler genug sind, um hoch entwickelte ihre eigene Zuordnung besser zu machen als der Programmierer kann, so register mit fast immer sinnlos ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top