Does C# allow double semicolon ; ; if so, are there any special ways?

I am writing a statement and it compiles, but the compiler [VS] never tells me that I put the semicolon two times.

This means in ASP.NET MVC 3

return Json(mydata);;

return Json(mydata);

Both of them compile, but the first is wrong in design pattern. Why doesn't it tell me about the two semicolons?

If there is no reason to use two semicolons, why doesn't it show an error?

If there is a special use of it, please show me where two semicolons is required to write a statement in C#.


Solution 1:

No, a double semi-colon is never required. I'm slightly surprised that the compiler doesn't complain that it's an unreachable statement, but apparently it's legal. It won't do any harm, but equally it's not a good idea.

Solution 2:

The empty statement is valid in all C-derived languages. The most common idiomatic use is in a for statement, e.g.:

for (; ; )
{
}

if their is a special use of it then show me where two semicolon is required to write a statement in c#

In the above example, two semicolons are required of course.

Solution 3:

That a double ;; is allowed, is for historical reasons. It's is a hangover from C style languages (which C# is based on).

C & C++ have the concept of pre-processor macros which are replaced in the code before the code is compiled e.g. trivial example AddAndSquare is a macro, not a function

#define AddAndSquare(X,Y) (X+Y)*(X+Y)
int Foo() {
   int a = 1, b = 2;
   return AddAndSquare(a, b);
}

goes to the compiler as

int Foo() {
   int a = 1, b = 2;
   return (A+B)*(A+B);
}

You can redefine macros to be different to their initial definition, also you can redefine them so they don't exist at all.

Given an assertion macro #define ASSERT(c) if(!c) throw new AssertionFailedException() you can have your coded littered with ASSERT statements.

void Foo(int x) {
    int y = x + 2;
    ASSERT(y != 0);
   int z = x / y;
    . . . .
}

Now consider that you only want the asserts in debug builds, but not in release builds, for release you redefine the macro to be empty (literally #define ASSERT). Now when Foo goes to the compiler for a release build, it looks like this

void Foo(int x) {
    int y = x + 2;
    ;
   int z = x / y;
    . . . .
}

There's now an empty statement where the ASSERT was, because there may or may not be a statement there (depending on build configuration), the compiler needs to be able to handle an empty statement.

Why this convention was kept in C# where there are nothing like C macros, I have no idea, but possibly because it causes little or no harm.

I would guess that multiple ; are elided by the compiler before it starts parsing code, therefore your unreachable ; is ignored by the compiler.