Semicolon after class declaration braces
Asked Answered
K

8

97

In C++ classes, why the semi-colon after the closing brace? I regularly forget it and get compiler errors, and hence lost time. Seems somewhat superfluous to me, which is unlikely to be the case. Do people really do things like:

class MyClass
{
.
.
.
} MyInstance;

I get it from a C compatibility point of view for structs and enums, but since classes aren't part of the C language I guess it's primarily there the keep consistency between similar declaration constructs.

What I was looking for was more related to design rationale rather than being able to change anything, although a good code completion IDE might trap this before compilation.

Knighterrantry answered 24/4, 2009 at 12:47 Comment(9)
This might help: cpptalk.net/…Norven
@Michael, thanks for the link. From a historical perspective it makes good sense, and if C++ allows all C grammer, and C++ classes are synonomous with structs, we are left with the necessary semi-colon at the end of the class.Knighterrantry
@Brian, yup serious question. I'm well aware I have to live with it but I curious about the rationale behind the design and implementation.Knighterrantry
Okay, but you perhaps should edit your question to include you wanted design rationale. As it is, it encourages people to ask questions like "why the curly brace"? :) You may be interested in reading Stroustrup's Design & Evolution of C++, although it covers more weightier matters than semi-colons at the end of classes.Categorical
@Brian, fair enough, and it was borderline as to whether or not to wiki it. The question was asked after leaving out a semi-colon in a regularly used header in a large build. It cost me half an hour, hence the visit to SO. Question edited as per your suggestion.Knighterrantry
Classes are essentially structs, the only difference is their default level of access (private vs public). So there is no difference with respect to semi-colons. I guess that is why I was so incredulous. :)Categorical
I recommend writing every class by first writing the "skeleton": class ClassName {\n private:\n public:\n }; and then filling in the details. Or, as you said, using an IDE that will do this for youLowrey
@BrianNeal, this question is rather old at this point, but I would argue that classes have a fundamental difference from structs in that they can also contain functions. I mean yeah, theyre really similar to structs, but default level of access is not the only difference, and the ability to encapsulate functions makes them fairly different. All this is just to say that I feel like noting some difference between them is justifiiable.Tryptophan
@RyanBlanchard structs can have member functions in C++.Categorical
P
57

The semi-colon after the closing brace in a type declaration is required by the language. It's been that way since the earliest versions of C.

And yes, people do indeed do the declaration you just put up there. It's useful for creating scoped types inside of methods.

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

  struct ADifferentType { int x; };
}

In this case, I think it's clear why the semi-colons are needed. As to why it's needed in the more general case of declaring in the header file I'm unsure. My guess is that it's historical and was done to make writing the compiler easier.

Plowman answered 24/4, 2009 at 12:50 Comment(3)
Why can't I just create scoped type without specifying MyInstance? It seams strange as you combine two actions: declaring new type and declaring new variable.Ezar
@Mykola you can do both. See the sample I addedPlowman
"was done to make writing the compiler easier." - this is still true today. For example trailing return types. Why do we need trailing return types? Because the C++ compilers are too stupid to parse the next 30 characters of the template definition in order to find out that T of decltype(T) exists. And then we can't use trailing return types, because compilers are too stupid again, so we need to type auto in front of the method so that the compiler knows it needs to wait for later. This "the programmer can make compilation easier" philosophy makes me quite upset with C++.Krys
E
92

The link provided by @MichaelHaren appears to provide the root cause. The semicolon (as others have pointed out) is inherited from C. But that doesn't explain why C used it in the first place. The discussion includes this gem of an example:

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

Older versions of C had an implicit int return type from a function unless declared otherwise. If we omit the ; at the end of the structure definition, we're not only defining a new type fred, but also declaring that main() will return an instance of fred. I.e. the code would be parsed like this:

struct fred { int x; long y; } main()
{ 
  return 0; /* invalid return type, expected fred type */
} 
Ensnare answered 22/5, 2014 at 14:53 Comment(1)
Yeah the implicit int return type would eff everything up here. Nice gemOndometer
P
57

The semi-colon after the closing brace in a type declaration is required by the language. It's been that way since the earliest versions of C.

And yes, people do indeed do the declaration you just put up there. It's useful for creating scoped types inside of methods.

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

  struct ADifferentType { int x; };
}

In this case, I think it's clear why the semi-colons are needed. As to why it's needed in the more general case of declaring in the header file I'm unsure. My guess is that it's historical and was done to make writing the compiler easier.

Plowman answered 24/4, 2009 at 12:50 Comment(3)
Why can't I just create scoped type without specifying MyInstance? It seams strange as you combine two actions: declaring new type and declaring new variable.Ezar
@Mykola you can do both. See the sample I addedPlowman
"was done to make writing the compiler easier." - this is still true today. For example trailing return types. Why do we need trailing return types? Because the C++ compilers are too stupid to parse the next 30 characters of the template definition in order to find out that T of decltype(T) exists. And then we can't use trailing return types, because compilers are too stupid again, so we need to type auto in front of the method so that the compiler knows it needs to wait for later. This "the programmer can make compilation easier" philosophy makes me quite upset with C++.Krys
B
17

I guess it's because classes are declarations, even when they need braces for grouping. And yes, there's the historical argument that since in C you could do

struct
{
  float x;
  float y;
} point;

you should in C++ be able to do a similar thing, it makes sense for the class declaration to behave in the same way.

Banff answered 24/4, 2009 at 12:51 Comment(0)
S
11

It's short for

class MyClass
{
.
.
.
};

// instance declaration
MyClass MyInstance;  // semicolon here

The semicolon after the curly braces of the class declaration is actually overkill, but it is how C++ is defined. The semicolon after the variable declaration is always needed and makes sense.

Sarad answered 24/4, 2009 at 12:52 Comment(2)
So, does C++ require a semi-colon after each declaration ?Impromptu
Note that, this way, you can't create an object of an anonymous class, while you can the other way.Eratosthenes
E
5

I do not use such declarations

class MyClass
{
.
.
.
} MyInstance;

But in this case I can understand why is semicolon there.
Because it is like int a; - variable declaration.

Probably for consistence as you can omit 'MyInstance' semicolon stays there.

Ezar answered 24/4, 2009 at 12:53 Comment(0)
B
2

In C/C++ the ; is a statement terminator. All statements are terminated with ; to avoid ambiguity (and to simplify parsing). The grammar is consistent in this respect. Even though a class declaration (or any block for that matter) is multiple lines long and is delimited with {} it is still simply a statement (the { } is part of the statement) hence needs to be terminated with ; (The ; is not a separator/delimitor)

In your example

class MyClass{...} MyInstance;

is the complete statement. One could define multiple instances of the declared class in a single statement

class MyClass{...} MyInstance1, MyInstance2;

This is completely consistent with declaring multiple instances of a primitive type in a single statement:

int a, b, c;

The reason one does not often see such desclaration of class and instance, is the instance could ?only? be a global variable, and you don't really often want global objects unless they are static and/or Plain Old Data structures.

Barnhill answered 25/4, 2009 at 8:0 Comment(1)
But function definition is a statement too but without semicolons.Knowable
R
1

It is needed after a struct for compatibility reasons, and how would you like this:

struct MyStruct { ... };
class  MyClass  { ... }    //inconsistency
Retch answered 24/4, 2009 at 14:30 Comment(1)
But what about namespace myNamespace { ... } // inconsistent but valid?Boeke
N
-1

We can define a class something {...}accum, trans; where accum and trans can be two objects of the class something. Therefore to declair an object of the class we use semi-colon after the class.

Neurasthenic answered 29/11, 2021 at 15:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.