Warum wurde das Register-Schlüsselwort erstellt?

Lesezeit: 8 Minuten

Benutzeravatar von ayushgp
ayushgp

Während des Lesens Keywords, die keine sind (oder Kommentare mit einem anderen Namen) durch Herb Sutter Dabei bin ich auf diese Zeilen gestoßen:

Das ist richtig, einige Schlüsselwörter sind semantisch äquivalent zu Leerzeichen, einem verherrlichten Kommentar.

Und

Wir haben gesehen, warum die C++-Sprache Schlüsselwörter als reservierte Wörter behandelt, und wir haben zwei Schlüsselwörter gesehen – auto und register –, die für ein C++-Programm keinen semantischen Unterschied machen. Verwenden Sie sie nicht; Sie sind sowieso nur Leerzeichen, und es gibt schnellere Möglichkeiten, Leerzeichen einzugeben.

Wenn die Stichworte gefallen auto(vielleicht nicht in C++11) und register wertlos sind, warum wurden sie dann geschaffen und verwendet?

Wenn es keinen Unterschied macht, die einzubeziehen register vor einer Variablen

#include<stdio.h>
int main(){
    register int a = 15;
    printf("%d\n%d\n",&a,a);
    return 0;
}

Warum gibt das obige Programm einen Fehler aus?

test_register.c: In Funktion ‘main’:

test_register.c:4:2: Fehler: Adresse der Registervariablen ‘a’ angefordert

printf(“%d\n%d\n”,&a,a);

Das folgende Programm funktioniert in C++.

#include<iostream>
int main(){
    register int a = 15;
    std::cout<<&a<<'\n'<<a;
    return 0;
}

  • Für die Kompatibilität mit dem C der Zeit?

    – Juanchopanza

    26. Mai 2016 um 9:18 Uhr


  • Sie waren in der Vergangenheit von Nutzen, als der Compiler nicht schlau genug war, allein über die Registrierung zu entscheiden

    – MM

    26. Mai 2016 um 9:19 Uhr

  • Es ist in modernem C nicht relevant. Möglicherweise ist es das, wenn Sie einen sehr alten Compiler verwenden

    – MM

    26. Mai 2016 um 9:23 Uhr

  • @ayushgp & kann nicht auf eine als `register deklarierte Variable angewendet werden

    – MM

    26. Mai 2016 um 9:40 Uhr

  • @ayushgp Ich finde es überhaupt nicht komisch, wenn man die angegebenen Bedeutungen bedenkt. In C kann die Adresse einer Registervariablen nicht übernommen werden, da die Variable eigentlich für die Registerspeicherung reserviert ist. In C++ ist es kann genommen werden, denn das Schlüsselwort register sagt (noch) nichts aus. Und es versteht sich von selbst, dass ein C-Frontend die C-Regeln respektiert, während ein C++-Frontend die C++-Regeln respektiert.

    – Theodoros Chatzigiannakis

    26. Mai 2016 um 9:48 Uhr


Benutzeravatar von Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

registrieren

In C, die register Die Speicherklasse wurde als Hinweis für den Compiler verwendet, um auszudrücken, dass eine Variable vorzugsweise in einem Register gespeichert werden sollte. Beachten Sie, dass der Hinweis zum Speichern von a register Variable in einem tatsächlichen Register kann berücksichtigt werden oder nicht, aber in jedem Fall gelten die relevanten Einschränkungen immer noch. Siehe C11, 6.7.1p6 (Hervorhebung von mir):

Eine Deklaration eines Bezeichners für ein Objekt mit Speicherklassenbezeichner register schlägt vor, dass der Zugriff auf das Objekt so schnell wie möglich erfolgt. Inwieweit solche Vorschläge wirksam sind, wird von der Umsetzung bestimmt.[footnote 121]

[footnote 121] Die Implementierung kann beliebig behandelt werden register Deklaration einfach als auto Erklärung. Unabhängig davon, ob adressierbarer Speicher tatsächlich verwendet wird oder nicht, wird die Adresse eines beliebigen Teils eines Objekts mit dem Speicherklassenbezeichner deklariert register kann nicht berechnet werden, entweder explizit (durch Verwendung des unären &-Operators, wie in 6.5.3.2 besprochen) oder implizit (durch Konvertieren eines Array-Namens in einen Zeiger, wie in 6.3.2.1 besprochen). Daher sind dies die einzigen Operatoren, die auf ein Array angewendet werden können, das mit einem Speicherklassenbezeichner deklariert wurde register sind sizeof und _Alignof.

In C++ ist es einfach ein ungenutztes reserviertes Schlüsselwort, aber es ist vernünftig anzunehmen, dass es aus Gründen der syntaktischen Kompatibilität mit C-Code beibehalten wurde.

Auto

In C, die auto Die Speicherklasse definiert eine Variable für die automatische Speicherung, wird jedoch normalerweise nicht verwendet, da funktionslokale Variablen verwendet werden auto standardmäßig.

Ebenso ist es vernünftig anzunehmen, dass es ursprünglich nur aus syntaktischen Kompatibilitätsgründen auf C++ übertragen wurde, obwohl es später seine eigene Bedeutung erhielt (Typ Inferenz).

  • das auto-Schlüsselwort ist, weil es am Anfang von C keinen Typ gibt, es gibt nur Speicherklassen. Wo wird das auto-C-Schlüsselwort verwendet?

    – phuklv

    26. Mai 2016 um 9:25 Uhr


  • @LưuVĩnhPhúc gab es immer int in C. denke ich auto von BCPL herumgehangen und sie haben es in C belassen, um das Portieren von Code von BCPL nach C einfacher zu machen

    – MM

    26. Mai 2016 um 10:03 Uhr


  • MM: Ironischerweise, auto i = 10; war sowohl in K&R als auch in C90 erlaubt, in welchem ​​Fall der Typ unter Verwendung des Impliziten abgeleitet wurde int Regel.

    – Grzegorz Szpetkowski

    26. Mai 2016 um 10:19 Uhr

  • Vor vielen, vielen Jahren (Ende der 80er) sah ich einen Entwickler, der unsere Software portierte; Er verbrachte ein paar Stunden damit, “register” blind vor die ersten drei Variablen in jeder Funktion einzufügen, und danach lief die gesamte Anwendung etwa 30 % schneller.

    – gnasher729

    26. Mai 2016 um 15:07 Uhr

  • @gnasher729: Ich hoffe, er hat eine Funktionsanfrage an den Compiler gesendet, “bitte schreiben Sie einen Registerzuordner”.

    – Steve Jessop

    26. Mai 2016 um 17:40 Uhr


Benutzeravatar von Tavian Barnes
Tavian Barnes

register in C diente zwei Zwecken:

  • Hinweis an den Compiler, dass die Variable aus Performancegründen in einem Register gespeichert werden sollte. Diese Verwendung ist heute weitgehend veraltet.
  • Verhindern Sie, dass der Programmierer die Variable auf eine Weise verwendet, die verhindern würde, dass sie in einem Register gespeichert wird. Diese Verwendung ist meiner Meinung nach nur etwas veraltet.

Dies ist ähnlich wie constdie

  • Hinweise an den Compiler, dass eine Variable im Nur-Lese-Speicher gespeichert werden kann.
  • Verhindert, dass der Programmierer in die Variable schreibt

Betrachten Sie als Beispiel diese vereinfachte Funktion:

int sum(const int *values, size_t length) {
    register int acc = 0;
    for (size_t i = 0; i < length; ++i) {
        acc += values[i];
    }
    return acc;
}

Der Programmierer hat geschrieben register um den Akkumulator vom Stack fernzuhalten, wodurch ein Speicherschreiben bei jeder Aktualisierung vermieden wird. Wenn die Implementierung in etwa so geändert wird:

// Defined in some other translation unit
void add(int *dest, int src);

int sum(const int *values, size_t length) {
    register int acc = 0;
    for (size_t i = 0; i < length; ++i) {
        add(&acc, values[i]);
    }
    return acc;
}

Das acc Variable kann nicht mehr in einem Register gespeichert werden, wenn ihre Adresse für die genommen wird add() anrufen, weil Register keine Adresse haben. Der Compiler wird also flaggen &acc als Fehler, der Sie darüber informiert, dass Sie wahrscheinlich die Leistung Ihres Codes durch die Verhinderung zerstört haben acc vom Leben in einem Register.

Dies war früher viel wichtiger, als Compiler dümmer waren und Variablen für eine ganze Funktion an einem einzigen Ort lebten. Heutzutage kann eine Variable den größten Teil ihres Lebens in einem Register verbringen und wird nur vorübergehend auf den Stapel verschoben, wenn ihre Adresse belegt ist. Das heißt, dieser Code:

/* Passed by reference for some reason. */
void debug(const int *value);

int sum(const int *values, size_t length) {
    int acc = 0;
    for (size_t i = 0; i < length; ++i) {
        acc += values[i];
    }
    debug(&acc);
    return acc;
}

verursacht hätte acc in älteren Compilern für die gesamte Funktion auf dem Stack zu leben. Moderne Compiler werden beibehalten acc in einem Register bis kurz vor dem debug() Anruf.

Moderner C-Code verwendet im Allgemeinen nicht die register Stichwort.

  • IMHO, die register Das Schlüsselwort könnte sehr nützlich sein, wenn es die Adresse einer Variablen nicht vollständig verbieten würde, aber dem Compiler erlauben würde, die so zurückgegebene Adresse ähnlich wie einen “restrict”-Zeiger zu behandeln. Also sowas wie sscanf(st, "%d", &value); könnte nach Belieben des Compilers konvertiert werden { int temp; sscanf(st, "%d", &temp); value=temp;}; wenn die Vorteile der Behandlung value als wäre seine Adresse nie aufgenommen worden, überwogen die Kosten für die Erstellung des Provisoriums.

    – Superkatze

    26. Mai 2016 um 19:14 Uhr

  • @supercat-Compiler machen diese Art von Transformation sowieso! Die einzige Einschränkung, die Sie aufheben würden, sind derzeit zwei log(&acc) Aufrufe innerhalb derselben Funktion müssen dieselbe Adresse sehen.

    – Tavian Barnes

    26. Mai 2016 um 19:29 Uhr

  • Gegenwärtig ist es Compilern untersagt, eine Variable vom Typ zu behalten int in einem Register, während auf einen Zeiger vom Typ zugegriffen wird int* wenn es möglich, aber nicht sicher ist, dass der Zeiger die Variable identifiziert, und ebenso für andere Typen. Wenn die Adresse einer Variablen noch nie verwendet wurde, beweist dies, dass ein Zeiger vom Typ int* unmöglich darauf zugreifen konnte, ist trivial. Wenn die Adresse einem externen Code ausgesetzt wurde, ist ein solcher Nachweis oft viel schwieriger, wenn nicht gar unmöglich.

    – Superkatze

    26. Mai 2016 um 19:47 Uhr


  • Wenn die Adresse einer automatischen Variablen noch nie einem externen Code ausgesetzt wurde, kann sie über Aufrufe an einen externen Code hinweg in einem Register zwischengespeichert werden. Sobald die Variable dem externen Code ausgesetzt wurde, muss ihr Wert jedoch bei jedem nachfolgenden Aufruf des externen Codes in den RAM geschrieben werden.

    – Superkatze

    26. Mai 2016 um 19:53 Uhr

  • Das werde ich mir merken register ist in der eingebetteten Programmierung nach wie vor hochaktuell.

    – chrylis -vorsichtig optimistisch-

    27. Mai 2016 um 2:49 Uhr

C99-Begründung bietet etwas mehr Kontext des Schlüsselworts register:

Begründung für International Standard – Programmiersprachen – C

§6.7.1 Speicherklassenspezifizierer

Denn die Adresse von a register Variable kann nicht genommen werden, Objekte der Speicherklasse register effektiv in einem Raum existieren, der sich von anderen Objekten unterscheidet. (Funktionen belegen noch einen dritten Adressraum.) Dies macht sie zu Kandidaten für eine optimale Platzierung, dem üblichen Grund für die Deklaration von Registern; aber es macht sie auch zu Kandidaten für eine aggressivere Optimierung.

  • Erwähnenswert ist, dass Compiler leicht feststellen können, ob die Adresse einer Variablen verwendet wird oder nicht, sozusagen register vermittelt keine zusätzlichen Informationen.

    – Benutzer541686

    27. Mai 2016 um 7:00 Uhr

  • @Mehrdad: Wenn “register” für globale Variablen erlaubt wäre, könnte es sehr nützliche Informationen liefern. Es könnte auch sehr nützliche Informationen liefern, wenn es dem Code erlaubt wäre, die Adresse von Registervariablen zu übernehmen aber die so genommene Adresse würde als ein Beschränkungs-qualifizierter Zeiger behandelt werden [meaning that a compiler would be allowed to keep a variable in a register across all pointer accesses except those which occur between the time a variable’s address is taken and the next time that variable is used by name].

    – Superkatze

    3. Juni 2016 um 16:34 Uhr

1405790cookie-checkWarum wurde das Register-Schlüsselwort erstellt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy