Semikolon nach Klassendeklarationsklammern

82

Warum in C ++ - Klassen das Semikolon nach der schließenden Klammer? Ich vergesse es regelmäßig und bekomme Compilerfehler und damit verlorene Zeit. Scheint mir etwas überflüssig, was wahrscheinlich nicht der Fall ist. Tun die Leute wirklich Dinge wie:

class MyClass
{
.
.
.
} MyInstance;

Ich verstehe es aus Sicht der C-Kompatibilität für Strukturen und Aufzählungen, aber da Klassen nicht Teil der C-Sprache sind, ist es meiner Meinung nach in erster Linie die Konsistenz zwischen ähnlichen Deklarationskonstrukten.

Was ich suchte, bezog sich eher auf das Design als auf die Möglichkeit, irgendetwas zu ändern, obwohl eine gute IDE für die Code-Vervollständigung dies möglicherweise vor dem Kompilieren abfängt.

SmacL
quelle
4
Dies könnte helfen: cpptalk.net/…
Michael Haren
@ Michael, danke für den Link. Aus historischer Sicht ist dies sinnvoll, und wenn C ++ alle C-Grammatiker zulässt und C ++ - Klassen mit Strukturen synonym sind, bleibt am Ende der Klasse das erforderliche Semikolon übrig.
SmacL
3
@ Brian, yup ernsthafte Frage. Ich bin mir bewusst, dass ich damit leben muss, aber ich bin gespannt auf die Gründe für das Design und die Implementierung.
SmacL
Okay, aber vielleicht sollten Sie Ihre Frage so bearbeiten, dass sie die gewünschten Designgründe enthält. So wie es ist, ermutigt es die Leute, Fragen zu stellen wie "Warum die geschweifte Klammer"? :) Vielleicht möchten Sie Stroustrups Design & Evolution of C ++ lesen, obwohl es am Ende des Unterrichts wichtigere Themen als Semikolons behandelt.
Brian Neal
@ Brian, fair genug, und es war grenzwertig, ob man es wiki macht oder nicht. Die Frage wurde gestellt, nachdem ein Semikolon in einem regelmäßig verwendeten Header in einem großen Build weggelassen wurde. Es hat mich eine halbe Stunde gekostet, daher der Besuch bei SO. Die Frage wurde gemäß Ihrem Vorschlag bearbeitet.
SmacL

Antworten:

47

Das Semikolon nach der schließenden Klammer in einer Typdeklaration wird von der Sprache benötigt. So ist es seit den frühesten Versionen von C.

Und ja, die Leute machen tatsächlich die Erklärung, die Sie gerade dort abgegeben haben. Dies ist nützlich, um Typen mit Gültigkeitsbereich innerhalb von Methoden zu erstellen.

void Example() {
  struct { int x; } s1;
  s1.x = 42;

  struct ADifferentType { int x; };
}

In diesem Fall ist mir klar, warum die Semikolons benötigt werden. Ich bin mir nicht sicher, warum dies im allgemeineren Fall der Deklaration in der Header-Datei erforderlich ist. Ich vermute, dass es historisch ist und gemacht wurde, um das Schreiben des Compilers zu vereinfachen.

JaredPar
quelle
Warum kann ich nicht einfach einen Typ mit Gültigkeitsbereich erstellen, ohne MyInstance anzugeben? Es ist seltsam, wenn Sie zwei Aktionen kombinieren: Deklarieren eines neuen Typs und Deklarieren einer neuen Variablen.
Mykola Golubyev
@ Mykola Sie können beides tun. Siehe das Beispiel, das ich hinzugefügt habe
JaredPar
69

Die Verknüpfung von @MichaelHaren vorgesehen scheint die schaffen Ursache . Das Semikolon (wie andere bereits betont haben) stammt von C. Aber das erklärt nicht, warum C es überhaupt verwendet hat. Die Diskussion beinhaltet dieses Juwel eines Beispiels:

struct fred { int x; long y; }; 
main() 
{ 
  return 0; 
} 

Ältere Versionen von C hatten einen impliziten int-Rückgabetyp von einer Funktion, sofern nicht anders angegeben. Wenn wir das ;am Ende der Strukturdefinition weglassen , definieren wir nicht nur einen neuen Typ fred, sondern deklarieren auch, dass main()eine Instanz von zurückgegeben wird fred. Dh der Code würde folgendermaßen analysiert:

struct fred { int x; long y; } main()
{ 
  return 0; /* invalid return type, expected fred type */
} 
Nathan
quelle
1
Ja, der implizite int-Rückgabetyp würde hier oben alles bewirken. Nettes Juwel
Gaspa79
17

Ich denke, das liegt daran, dass Klassen Deklarationen sind, auch wenn sie zum Gruppieren geschweifte Klammern benötigen. Und ja, es gibt das historische Argument, dass man es seit C tun könnte

struct
{
  float x;
  float y;
} point;

Wenn Sie in C ++ in der Lage sein sollten, etwas Ähnliches zu tun, ist es sinnvoll, dass sich die classDeklaration genauso verhält.

entspannen
quelle
10

Es ist kurz für

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

Das Semikolon nach den geschweiften Klammern der Klassendeklaration ist eigentlich übertrieben, aber so wird C ++ definiert. Das Semikolon nach der Variablendeklaration wird immer benötigt und ist sinnvoll.

Stefan Steinegger
quelle
1
Benötigt C ++ nach jeder Deklaration ein Semikolon?
Loai Nagati
1
Beachten Sie, dass Sie auf diese Weise kein Objekt einer anonymen Klasse erstellen können, während Sie dies auf die andere Weise tun können.
Kevin
5

Ich verwende solche Erklärungen nicht

class MyClass
{
.
.
.
} MyInstance;

Aber in diesem Fall kann ich verstehen, warum es dort ein Semikolon gibt.
Weil es wie int a;- Variablendeklaration ist.

Wahrscheinlich aus Gründen der Konsistenz, da Sie das Semikolon "MyInstance" weglassen können.

Mykola Golubyev
quelle
3

Es wird structaus Kompatibilitätsgründen nach a benötigt , und wie möchten Sie dies:

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency
Zifre
quelle
1
Aber was ist mit namespace myNamespace { ... } // inconsistent but valid?
Chris K
3

In C / C ++ ist das; ist ein Anweisungsabschluss. Alle Anweisungen werden mit beendet; um Mehrdeutigkeiten zu vermeiden (und das Parsen zu vereinfachen). Die Grammatik ist in dieser Hinsicht konsistent. Obwohl eine Klassendeklaration (oder ein beliebiger Block) mehrere Zeilen lang ist und durch {} begrenzt ist, handelt es sich immer noch nur um eine Anweisung (die {} ist Teil der Anweisung), die daher mit beendet werden muss. (Das; ist kein Trennzeichen / Trennzeichen)

In deinem Beispiel

class MyClass{...} MyInstance;

ist die vollständige Aussage. Man könnte mehrere Instanzen der deklarierten Klasse in einer einzigen Anweisung definieren

class MyClass{...} MyInstance1, MyInstance2;

Dies steht im Einklang mit der Deklaration mehrerer Instanzen eines primitiven Typs in einer einzigen Anweisung:

int a, b, c;

Der Grund, warum man eine solche Deklaration von Klasse und Instanz nicht oft sieht, ist, dass die Instanz nur? Seien Sie eine globale Variable, und Sie möchten nicht wirklich oft globale Objekte, es sei denn, es handelt sich um statische und / oder einfache alte Datenstrukturen.

Roger Nelson
quelle
2
Die Funktionsdefinition ist aber auch eine Aussage, jedoch ohne Semikolons.
Jiapeng Zhang