Demi-Colon après accolades de déclaration de classe

Excuses à l’avance pour ce qui est probablement une question stupide, mais dans les classes C ++, pourquoi le point-virgule après l’accolade fermante? Je l’oublie régulièrement et j’obtiens des erreurs de compilation, et par conséquent du temps perdu. Cela me semble un peu superflu, ce qui est peu probable. Les gens font-ils vraiment des choses comme

class MyClass { . . . } MyInstance; 

Edit: Je comprends le sharepoint vue de la compatibilité C pour les structs et les enums, mais comme les classes ne font pas partie du langage C, je suppose que c’est avant tout la cohérence entre les constructions de déclaration similaires. Ce que je cherchais était plus lié à la logique de conception qu’à la capacité de changer quoi que ce soit, bien qu’un IDE de bonne exécution du code puisse le bloquer avant la compilation.

Le point-virgule après l’accolade fermante dans une déclaration de type est requirejs par le langage. C’est comme ça depuis les premières versions de C.

Et oui, les gens font effectivement la déclaration que vous venez de présenter. C’est utile pour créer des types de scope à l’intérieur des méthodes.

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

Dans ce cas, je pense qu’il est clair que les points-virgules sont nécessaires. Quant à savoir pourquoi il est nécessaire dans le cas plus général de la déclaration dans le fichier d’en-tête, je ne suis pas sûr. Je suppose que c’est historique et a été fait pour faciliter l’écriture du compilateur.

Le lien fourni par @MichaelHaren semble fournir la cause première . Le point-virgule (comme d’autres l’ont fait remarquer) est hérité de C. Mais cela n’explique pas pourquoi C l’a utilisé en premier lieu. La discussion inclut ce joyau d’un exemple:

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

Les versions antérieures de C avaient un type de retour int implicite d’une fonction, sauf indication contraire. Si nous omettons le ; A la fin de la définition de la structure, nous ne définissons pas seulement un nouveau type fred , mais nous fred également que main() renverra une instance de fred . Ie code serait analysé comme ceci:

 struct fred { int x; long y; } main() { return 0; /* invalid return type, expected fred type */ } 

Je suppose que c’est parce que les classes sont des déclarations, même lorsqu’elles ont besoin d’accolades pour le regroupement. Et oui, il y a l’argument historique que, puisque dans C vous pourriez faire

 struct { float x; float y; } point; 

En C ++, vous devriez pouvoir faire la même chose, il est logique que la déclaration de class se comporte de la même manière.

C’est court pour

 class MyClass { . . . }; // instance declaration MyClass MyInstance; // semicolon here 

Le point-virgule après les accolades de la déclaration de classe est en fait excessif, mais c’est comment C ++ est défini. Le point-virgule après la déclaration de variable est toujours nécessaire et a un sens.

Je n’utilise pas de telles déclarations

 class MyClass { . . . } MyInstance; 

Mais dans ce cas, je peux comprendre pourquoi le point-virgule est là.
Parce que c’est comme int a; – déclaration de variable.

Probablement pour la cohérence comme vous pouvez omettre le point-virgule «MyInstance» rest là.

Il est nécessaire après une struct pour des raisons de compatibilité, et comment aimeriez-vous cela:

 struct MyStruct { ... }; class MyClass { ... } //inconsistency 

En C / C ++ le; est un terminateur de déclaration. Toutes les déclarations sont terminées avec; pour éviter toute ambiguïté (et simplifier l’parsing syntaxique). La grammaire est cohérente à cet égard. Même si une déclaration de classe (ou n’importe quel bloc) comporte plusieurs lignes et est délimitée par {}, il s’agit simplement d’une déclaration (le {} fait partie de l’instruction) et doit donc être terminé par; (Le n’est pas un séparateur / délimiteur)

Dans ton exemple

 class MyClass{...} MyInstance; 

est la déclaration complète. On pourrait définir plusieurs instances de la classe déclarée dans une seule instruction

 class MyClass{...} MyInstance1, MyInstance2; 

Ceci est tout à fait compatible avec la déclaration de plusieurs instances d’un type primitif dans une seule instruction:

 int a, b, c; 

La raison pour laquelle on ne voit pas souvent une telle séparation de la classe et de l’instance, est-ce que l’instance pourrait? Seulement? être une variable globale, et vous ne voulez pas vraiment d’objects globaux à moins qu’ils ne soient des structures statiques et / ou Plain Old Data.