11

The C# language specification defines the empty-statement grammar production, which allows me to do something like this:

static void Main(string[] args)
{
    ; ; ;
}

Why would Microsoft include this grammar production in the C# language? Does it have a useful purpose?

James Jones
  • 8,653
  • 6
  • 34
  • 46

13 Answers13

14
while (GetWhitespace(textStream))
    ;
Jeffrey L Whitledge
  • 58,241
  • 9
  • 71
  • 99
  • Microsoft say it can be used for null body as i did already, but my code base tool (resharper) say use empty method instead, also people say `while();` is like `while(){;}` which is more code than `while(){}` so what is what and is there any performance overheat? – Hassan Faghihi Oct 01 '16 at 10:32
11

I personally would never use an empty statement. If I for some bizarre reason wanted to play code golf and write something like

while(Foo(x++)) ;

I'd be more inclined to use {} instead of ; as the "do nothing statement". I think that is more clear.

Pretty much it's there for historic reasons. There's nothing there that you cannot also do with {}.

UPDATE: I just thought of one possible usage case. In a debug build it allows you to put a breakpoint somewhere that you are guaranteed that you can break at which is not going to have any side effect when you step. If the code surrounding the breakpoint is particularly complicated it might be useful.

UPDATE UPDATE: I am WRONG WRONG WRONG. That doesn't work. It just moves the breakpoint to the next statement. How irksome.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 4
    Though, golfing is usually by character, and `{}` is 1 more character than `;`... :p – Tanzelax Mar 03 '10 at 20:20
  • 5
    BTW, you can't set a breakpoint at an empty statement. It skips over the breakpoint and brings you to the next non-empty statement. Just tried it... – James Jones Mar 03 '10 at 20:28
  • If you have a second Eric could you add a comment to my answer on this question whether I'm on base or not. – Chris Marisic Mar 03 '10 at 20:31
5

C# inherits a lot from the C family, where you can do things like

for (i = 0; i < n; v[i++] = 1);

or

while (testSomeCondition());

That is, run a loop with an empty body where the "meat" is inside the brackets.

While one can debate about their merits and dangers, these are pretty common programming idioms in the C programming world, so this backward compatibility makes it easier for C/C++/Java programmers to learn C#.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
5

Here are two uses:

while(DoSomething()) ;

and

void M() {
    if(someCondition) goto exit;
    // ...
    exit: ;
}

There are many others. It's a useful device anytime there is nothing to do but a statement is required.

jason
  • 236,483
  • 35
  • 423
  • 525
  • 6
    I would remove that goto label and make `goto exit` a `return;`. This is awful C#. – Dykam Mar 03 '10 at 20:18
  • 12
    goto has its place, maybe not in Jason's context, but it is perfectly valid. – Yuriy Faktorovich Mar 03 '10 at 20:19
  • agree, if you want to write gotos may be you decomposed your task not that well – Andrey Mar 03 '10 at 20:19
  • 1
    Sidenote, I am not anti goto, goto is just one of those things which are to be used very, very carefully. – Dykam Mar 03 '10 at 20:20
  • 1
    http://weblogs.asp.net/stevewellens/archive/2009/06/01/why-goto-still-exists-in-c.aspx – Yuriy Faktorovich Mar 03 '10 at 20:23
  • Actually, I've used the empty statement *exactly* like this in a code generator for a state machine. Sometimes code would follow the label, but not always - the empty statement suppressed a compiler warning that liked to appear in the latter case. – Sam Harwell Mar 03 '10 at 20:31
  • 2
    goto is fundemental. Nearly all execution flow logic compiles with goto instructions. Purposely avoiding them leads to confusing logic. Look at Microsoft's .NET souce code and you will find goto is used fairly often. – AMissico Mar 03 '10 at 20:31
  • 3
    Breaking out of deeply nested loops? – tomfanning Mar 03 '10 at 20:40
  • 1
    To all those who parrot NO GOTO - read the above comments please. Goto is fundamental, and has places it's a good option. For example a return statement in deep loop is a GOTO! – Preet Sangha Mar 03 '10 at 21:01
  • 1
    @tomfanning, exactly. Goto is a clean way to do this. – Dykam Mar 03 '10 at 21:03
  • 1
    I agree as well. I've run across some awful code that was made needlessly complex because of a dogmatic avoidance of GOTOs. Besides, successful developers who started with assembler or early FORTRAN used GOTOs through careful and thoughtful programming practices. – Ed Power Mar 03 '10 at 21:34
2

It allows have blocks of code IFDEF'd out, and the surrounding code still build. eg

if(true){
#if(DEBUG)
System.Console.WriteLine("Debug comment");
#endif
}

which could be written as an empty block, if you dislike brackets:

if(true)
#if(DEBUG)
   System.Console.WriteLine("Debug comment")
#endif
;
Simeon Pilgrim
  • 22,906
  • 3
  • 32
  • 45
  • 1
    Yes it does, {} looks pretty empty to me, about as empty as {;}, the {} acts as a block marker, so does the ; in the second case. – Simeon Pilgrim Mar 03 '10 at 20:53
  • While {} is "a statement that doesn't do anything", it's not the C# "empty statement" as defined here: http://msdn.microsoft.com/en-us/library/aa664739%28VS.71%29.aspx – tomfanning Mar 03 '10 at 21:12
  • Ok, good point, I see he's referring to the grammar rule, thus your correct. Therefore grammar the rule you point to is the perfect answer. – Simeon Pilgrim Mar 03 '10 at 21:49
1

Good practice or not, some people use this:

while (!SomeCondition)
    ; // <-- body of the while loop is an empty statement
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
1

Why would Microsoft include this grammar production in the C# language?

the main answer to this question is: C# is C-like language and to make life of different developers easier MS decided to make most basic syntax elements compatible with other c-like languages. and it is good.

Andrey
  • 59,039
  • 12
  • 119
  • 163
1

This is an assumption but I would assume it goes to the base grammar for the compiler. Relating it to set theory the "empty set" is inside every single set. That the ; really is to define a set of lexical operations which always must define the ; which also would accept the base case which is empty statement.

Chris Marisic
  • 32,487
  • 24
  • 164
  • 258
  • First off, the empty set is a *subset* of every set, but not a *member* of every set; "inside" is ambiguous as to which you mean. Second, I'm not following your point about how that applies to grammar design. – Eric Lippert Mar 03 '10 at 23:23
  • It's been a while since my compiler theory has ever been needed but in I believe the lexical parser that evaluates whether expressions are valid that are like A | [B]A | [B]C[B]A where A in this case is the ; – Chris Marisic Mar 04 '10 at 15:18
0
if (b1)
   if (b2) else;
else
   //code

withoud this ; this will be painful. but this is not best way to write ifs also. but acceptable.

Andrey
  • 59,039
  • 12
  • 119
  • 163
  • 1
    What's a use case of this? Looks pretty useless. – Dykam Mar 03 '10 at 20:17
  • Not for every construct there is a really useful use case. Sometimes it might just be convenient when tweaking code and testing stuff. – Sebastian Mach Mar 03 '10 at 20:18
  • it is useful. if you want to write else it will be one for innermost if, like bracket. but i want to have else in outer most if. – Andrey Mar 03 '10 at 20:18
  • But if you format your code properly and have brackets around your if statements, you won't have this problem at all. – Charles Boyung Mar 03 '10 at 20:21
  • i didn't say there is a problem. i showed example of using empty statement, i didn't say that you should use it. also C# compiler will give you a warning for that. – Andrey Mar 03 '10 at 20:23
0

Eric Lippert's a good person to ask.

Mostly, I suppose it's because it wouldn't cause any harm and it simplified their handling of the grammar. Also, why restrict people when you don't have to?

Jim L
  • 2,297
  • 17
  • 20
0

For what it's worth, a good rule of thumb is that you should have stepped through in the debugger every line of code you write, at least once for each possible execution path

ref: Possible mistaken empty statement

Asad
  • 21,468
  • 17
  • 69
  • 94
0

So some genius could write for(;;) instead of while(true). Like for an interview test.

Ed Power
  • 8,310
  • 3
  • 36
  • 42
  • Oops-good catch. Here's a treatment on their assembly level equivalence: http://stackoverflow.com/questions/2288856/when-implementing-an-infinite-loop-is-there-a-difference-in-using-while1-vs-fo – Ed Power Mar 03 '10 at 21:25
0

Imagine you have some code that you want to extend by a new feature:

void DoSomething()
{
    // ...
    NewMethod();
}

Now you introduce a new member called NewMethod. However you don´t have the time to implement it appropriately and leave it empty:

public void NewMethod() { }

Some time later you can finally implement the code of that member without having to bother where and how to call it, because that was already done before.

You can also create an interface which you don´t implement. This way you only define what to do, but not how.

Another possible scenario is to have a virtual member that usually does nothing, but in a few cases (some specific implementation) you want the method to return a specific value. See this post for example: Virtual methods without body

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111