tags:

views:

607

answers:

5

I was wondering why C# requires me to use break in a switch statement although a fall-through semantics is by definition not allowed. hence, the compiler could generate the break at the end of each case-block and save me the hassle.

However, there is one scenario (which has already been discussed on this site) which I could come up with that might be the reason for the explicit usage of break:

switch (foo) {
    case 0:
    case 1:
        bar();
        break;
    default:
        break;
}

Here, the method bar() is called if foo has either the value 0 or 1.

This option would break in the truest sense of the word if the compiler would generate break statements by itself. Is this it, is this the reason why the break is compulsory or are there any other good reasons?

+26  A: 

I suspect that the reason C# requires the developer to place a break or terminal statement at the end of each case is for clarity.

It avoids newcomers to the language from assuming that switch( ) in C# behaves like switch in C or C++ where fall through behavior occurs. Only in the cases of adjacent empty cases does fall through occur in C# - which is relatively obvious.

EDIT: Actually, in C# fallthrough is always illegal. What is legal, however, is having a single case associated with two or more labels. Eric Lippert writes at length about this behavior and how it differs from C/C++ switch statements.

You may be interested in reading this article on Eric Lipperts blog.

LBushkin
+1 for the link to Eric Lippert's, er, blog ;-). Yes, it might be clarity that drove this design decision.
Uwe Honekamp
It also allows the JIT flexibility to rearrange the code for optimizations without worrying about breaking something due to fall-through.
Scott Dorman
@ScottDorman - There is no fall-through... so reorganization wouldn't change anything if the break didn't need to be there. If there was fall-through, and code re-ordering could cause a problem, then the break wouldn't be required anyways.
RHSeeger
Crikey, they made C# `switch` nearly as clear as VB `Select Case`! But not quite, IMHO `case 0: case 1:` is a bit wordy and confusing compared to `Case 0, 1`
MarkJ
A: 

My understanding of the matter is that it was included to match C++ syntax.

STW
Hm, but AFAIK C++ does not require the break statement because C++ - like C - allows for case-blocks to fall through.
Uwe Honekamp
+4  A: 

By making break optional, you open yourself up to bugs like this:

switch (thing_result)
{
    case GOOD_THING:
        IssueReward();
        // UH-OH, missing break!
    case BAD_THING:
        IssuePunishment();
        break;
}

The C# language designers have tried to help programmers avoid pitfalls in the languages that came before it, generally by forcing the programmer to be more explicit (e.g. explicit use of the 'override' or 'new' keyword for implementing or shadowing virtual members).

bobbymcr
A: 

If you wouldn't need to append a break, there is a problem

switch (number)
{
    case 0:
    case 1:
        DoSomething();
}

What happens if number == 0? Is this an empty case which does not do anything or will DoSomething() be executed?

Oliver Hanappi
Sorry, but that's not true. When you add a break after the DoSomething() call, the C# code would be valid and for both cases, 0 and 1, the DoSomething() method would be called.
Oliver Hanappi
@RHSeeger, you're wrong.
Phong
@Phong, I removed my comment because part of it was correct. It was correct that the break statement only adds verbosity and doesn't avoid confusion. But it was incorrect in that the 0 case does do something, what the 1 case does... since it shares the body with the 1 case.
RHSeeger
+22  A: 

The question presupposes a falsehood and therefore cannot be answered. The language does NOT require a break at the end of a switch section. The language requires that the statement list of a switch section must have an unreachable end point. "break" is just the most commonly used statement that has this property. It is perfectly legal to end a switch section with "return;", "goto case 2;", "throw new Exception();" or "while (true) {}" (or in some cases, continue, though that's usually a bad idea.)

The reason we require a statement list with an unreachable endpoint is to enforce the "no fall through" rule.

If your question is better stated as "why doesn't the compiler automatically fix my error when I fail to produce a switch section with a statement list with an unreachable end point, by inserting a break statement on my behalf?", then the answer is that C# is not a "make a guess about what the developer probably meant and muddle on through" sort of language. Some languages are -- JScript, for example -- but C# is not.

We believe that C# programmers who make mistakes want to be told about those mistakes so that they can intentionally and deliberately correct them, and that this is a good thing. Our customers tell us that they do not want the compiler to make a guess about what they meant and hope for the best. That's why C# also does not make a guess about where you meant to put that missing semicolon, as JScript does, or silently fail when you attempt to modify a read-only variable, as JScript does, and so on.

Eric Lippert
?? The accepted answer refers to Eric's blog and his own answer gets downvoted? Voted it up again.
SolutionYogi
Well, SolutionYogi, not everyone agrees with me. I have no reason to imagine everyone would; everyone is entitled to their own opinion about why the language was designed as it was. I appreciate the gesture, but really, don't stress about it. :)
Eric Lippert
Well, Eric, I agree with you 100% and I want to chime in with my vote so that others do pay attention to your answer! And I am not at all stressing about it. I religiously follow your SO answers/comments as I learn a great deal from them. You are not only very knowledgeable, but you share your knowledge through your impeccable writing. I am a big fan of yours and whenever you are in NJ/NY, do let me know, I would like to buy you drinks/dinner! :)
SolutionYogi
Thanks and +1 for the explanation. I'm fully aware that e.g. using return at the end of a case block is also fine with the compiler and should have put more thinking in formulating the question.
Uwe Honekamp
Still, the C# compiler has defaults for many things, and tries to infer programmer intent in many cases (IE methods are private non virtual by default on classes). It's my humble opinion that a implicit break after a case would have been a resonable default even if it's not how the C switch behaves (I say that because I'm not a C developer). An implicit break should't be classified as a guess, it could be a well defined behavior, but I guess that would have made existing C developers confused :)
Pop Catalin
Making existing C developers confused is a large number of points against a feature. A great many of our developers come to us from C, in part because the syntaxes are so superficially similar.
Eric Lippert
How about having another swtich style with auto breaking? But I guess that creates more overhead for language designers, right? Maybe like caseof (foo) ... case 0 ... case 1 ... with no break.
Joan Venge
And then we'd have two ways to do almost exactly the same thing -- to do a language feature that is pretty old and clunky in the first place. Tweaking "switch" doesn't advance the state of the art in any way. And providing two confusingly-similar ways to do the same thing creates user confusion and large test costs for us. So that's unlikely to happen.
Eric Lippert
Makes sense Eric. Hehe.
Joan Venge