Warum definiert GCC den unären Operator ‘&&’, anstatt nur ‘&’ zu verwenden?

Lesezeit: 4 Minuten

Benutzer-Avatar
Jeremy

Wie in dieser Frage besprochen, definiert GCC nicht standardmäßige unäre Operatoren && um die Adresse eines Etiketts zu übernehmen.

Warum wird ein neuer Operator definiert, anstatt die vorhandene Semantik von zu verwenden? & Operator und/oder die Semantik von Funktionen (wobei foo und &foo beide liefern die Adresse der Funktion foo())?

  • Ich denke, die eigentliche Frage ist: „Warum haben sie es nicht so definiert? __address_of_label(label)?”

    – Benutzer694733

    28. April 2015 um 8:03 Uhr

  • Verwandt: gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html

    – PP

    28. April 2015 um 11:11 Uhr

Benutzer-Avatar
Sebastian Redl

Label-Namen stören andere Bezeichner nicht, da sie nur in Gotos verwendet werden. Eine Variable und ein Label können denselben Namen haben, und in Standard-C und C++ ist aus dem Kontext immer klar, was gemeint ist. Das ist also vollkommen gültig:

name:
  int name;
  name = 4; // refers to the variable
  goto name; // refers to the label

Die Unterscheidung zwischen & und && wird daher benötigt, damit der Compiler weiß, welche Art von Namen zu erwarten ist:

  &name; // refers to the variable
  &&name; // refers to the label

  • Hi. Wenn Sie nur ein bisschen klarstellen können, bzgl Label names live in a completely separate namespace from other identifiers..ich werde dankbar sein. ich dachte namespace existiert in C++ 🙂

    – Sourav Ghosh

    28. April 2015 um 8:09 Uhr


  • Der verwirrende Verweis auf “Namespace” wurde entfernt. Der Standard verwendet “Namensraum”. Dies hängt nicht mit dem C++-Namespace-Feature zusammen. Es bedeutet nur, dass die Namen nicht stören.

    – Sebastian Redl

    28. April 2015 um 8:13 Uhr

Benutzer-Avatar
hackt

GCC hat dies hinzugefügt Verlängerung zum Initialisieren eines statischen Arrays verwendet werden, das als Sprungtabelle dient:

static void *array[] = { &&foo, &&bar, &&hack };  

Wo foo, bar und hack sind Etiketten. Dann kann ein Label mit Indizierung wie folgt ausgewählt werden:

goto *array[i];   

Standard sagt das

C11: 6.2.1 Gültigkeitsbereich von Identifikatoren (p1):

Ein Bezeichner kann eine bezeichnen Objekt; eine Funktion; ein Tag oder ein Mitglied einer Struktur, Vereinigung oder Aufzählung; ein Typedef-Name; a Markenname; ein Makroname; oder ein Makroparameter.

Weiter heißt es in Abschnitt 6.2.3:

Wenn an irgendeiner Stelle in einer Übersetzungseinheit mehr als eine Deklaration eines bestimmten Bezeichners sichtbar ist, macht der syntaktische Kontext Verwendungen eindeutig, die sich auf unterschiedliche Entitäten beziehen. Somit gibt es getrennte Namensräume für verschiedene Kategorien von Bezeichnern wie folgt:

Labelnamen (disambiguiert durch die Syntax der Label-Deklaration und -Verwendung);

– das Stichworte von Strukturen, Vereinigungen und Aufzählungen (disambiguiert durch folgendes any32) der Schlüsselwörter struct, unionoder enum);

– das Mitglieder von Strukturen oder Gewerkschaften; Jede Struktur oder Union hat einen separaten Namensraum für ihre Mitglieder (disambiguiert durch den Typ des Ausdrucks, der für den Zugriff auf das Mitglied über die . oder -> Operator);

— alle anderen Bezeichner, sogenannte gewöhnliche Bezeichner (in gewöhnlichen Deklaratoren oder als Aufzählungskonstanten deklariert).

Das bedeutet, dass ein Objekt und ein Etikett können durch dieselbe Kennung bezeichnet werden. Um den Compiler an dieser Stelle wissen zu lassen, dass die Adresse von foo ist die Adresse eines Etiketts, nicht die Adresse eines Objekts foo (falls vorhanden), GCC definiert && Operator für die Adresse des Etiketts.

  • Auch wenn es schön an meine Zeit mit dem Z80 erinnert, bezweifle ich, dass dies überhaupt eine gute Idee für C ist – besonders wenn das gleiche Ergebnis mit nur etwas mehr Arbeit mit beiden erreicht werden könnte switch (GCC postuliert diese Alternative ausdrücklich) oder ein Array von Funktionszeigern (die ich gerade erfunden habe). Sogar GCC sagt: „Benutze das nur, wenn du es wirklich musst“, und es ist schwer, sich eine Situation vorzustellen, in der man es tut möchten wirklich müssen! Interessant zu lernen, aber in praktischer Hinsicht bestenfalls meh.

    – Unterstrich_d

    8. Januar 2016 um 11:16 Uhr


  • @underscore_d: Ich denke, das Feature geht auf die Tage zurück, bevor die Betreuer von gcc verrückt wurden, aggressive Optimierungen für moderne CPUs zu verfolgen, und stattdessen versuchten, Programmierern Tools zu geben, die sie verwenden konnten, um effizienten Code für einfachere CPUs in Fällen zu generieren, in denen Leistung eine Rolle spielte. Ich kann mir leicht Fälle vorstellen, in denen die Möglichkeit, ein “Goto” direkt zu einer Adresse in einem Array auszuführen, einer Anwendung ermöglichen könnte, mehr als 10 % zu erreichen. gesamt Leistungsgewinn (20 % Gewinn in einem Teil des Codes, in dem das Programm die Hälfte seiner Zeit verbringt).

    – Superkatze

    1. Oktober 2016 um 22:18 Uhr

1340810cookie-checkWarum definiert GCC den unären Operator ‘&&’, anstatt nur ‘&’ zu verwenden?

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

Privacy policy