13

I'm having hard time understanding, why the compiler requires using break statement. It's not possible to miss it since the fall through is now allowed. I see the reason for the break in C or C++, but is it needed here.

Why it's not a built-in behavior to break after a case is over ? Isn't it just a syntax with no semantic?

Sorry, if it's a stupid question.

EDIT: The fall through is allowed only when the case is empty. When there is a statement there you can't omit the break statement. So, it's a different matter.

anthares
  • 11,070
  • 4
  • 41
  • 61
  • 3
    Probably just to keep the C lads / lasses happy as they migragte into a new language. I take your point though about why make it mandatory... – Martin Milan Mar 02 '10 at 13:09
  • 1
    I think it's because it's inevitably going to be read by people not so familiar with c# but are familiar with the C/C++ syntax. Having the explicit break aids readability for everyone even though it serves no purpose. It's effectively backwards compatible. – Dolbz Mar 02 '10 at 13:17
  • 1
    Pithy C++ community member answer: "Because the language requires it." – Greg D Mar 02 '10 at 14:52
  • 1
    @Dolbz: Aiding readability is a completely valid purpose. – Sam Harwell Mar 02 '10 at 15:36
  • Fallthrough _is_ allowed for "empty cases" – Sebastian Mach Jan 31 '12 at 09:19
  • Fallthrough *is also* allowed for *not empty cases* but you have to state them explicitly with `goto label`. – Oliver Jan 31 '12 at 09:33
  • Having C syntax and Pascal semantics would be confusing. – Carsten S Feb 29 '16 at 14:52

4 Answers4

10

The compiler doesn't so much 'need' the break statements, it demands them.

This was a design decision. It keeps the code semantically close to C and C++ while eliminating the pitfalls of fall-through that was always a debatable 'feature' of the C languages.

H H
  • 263,252
  • 30
  • 330
  • 514
  • So, it just for clarification and has not any actual role ? – anthares Mar 02 '10 at 13:19
  • 3
    @anthares: You could say that. The break could easily be inserted by the compiler, the programmer has no choice here. But 'readability' is an important role for language constructs. – H H Mar 02 '10 at 13:23
  • It does serve a role. Switch is translated to goto statements in the IL and that is to have greater speed. lets say you have 10-20 cases; With if/else if you would have an average of 10 comparisons to get to the right case where as with the goto generated is much faster. – Thanos Papathanasiou Mar 02 '10 at 13:23
  • 3
    @ ThanosPapathanasiou: that makes no sense. Eliminating the break does not make the compiler treat the switch any different. – H H Mar 02 '10 at 13:25
  • That was may wondering exactly - does it have a significant role for the compiler or it is a "readability" / "clarification" feature. Thanks! – anthares Mar 02 '10 at 13:29
  • @Henk Holterman: yes it doesn't change how the compiler treats the switch but it clarifies where to place another jump command to exit the switch. maybe I didn't express myself well enough before. – Thanos Papathanasiou Mar 02 '10 at 13:47
  • 4
    Thanos, I don't believe that either. The compiler can assume a break any time it needs to, and apply other optimizations as well. – H H Mar 02 '10 at 14:21
  • I agree with Henk. I don't think that there is need to clarify where to place another jump command to exit the switch. It is well-known without the break. – anthares Mar 02 '10 at 14:26
  • In general I like the fact that there is a lot of overlap between the syntax of C# and C, it keeps things simple. So I would be disappointed if Microsoft had implemented a different definition of switch, in which a break occurred even if the break keyword was not present. I realise that C# and C are not meant to be subsets of supersets of each other, but it's nice to keep copy-and-paste compatibility wherever possible. – Stephen Holt Oct 29 '13 at 16:34
  • @anthares: I would suggest that it's a manifestation of what I consider a good language design philosophy: if a language is very similar to another language, every construct--whether or not the designer likes it--should either behave as it does in the other language *or else generate a compilation error*. Consider, for example, the question of what value should be represented by the integer constant "012". In C, it represents the value ten. Java follows C's lead, also having it represent ten. The designers of C# apparently didn't like that "feature", so they made it represent twelve. – supercat Feb 09 '14 at 21:52
  • 1
    @anthares: Personally, I think the proper approach should have been analogous to the one C# took with `switch`/`break`: figure that since the programmer might have meant ten and might have meant 12, the compiler should reject the code rather than assume either meaning. If a compiler can distinguish that there are multiple things a programmer might have intended something to mean, requiring the programmer to disambiguate before code compiles is not nearly as bad as having the compiler accept a program that doesn't do what the programmer intended. – supercat Feb 09 '14 at 21:57
  • The thing is that fallthrough __is__ allowed if the statement is empty. Only non-empty fall-through is forbidden. – Sebastian Mach Sep 14 '15 at 08:24
3

The break statement in c# was a design decision by the creators of the language...Essentially they wanted an "unambiguous" break statement, a break statement that would only work one way. In short, they didn't want fall-through, and if they had just prevented fall-through without including "break," it would have broken backwards compatibility with c++.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • OK why then this behavior is not built-in without the need of explicit break statement in the end of the cases. They can do it implicitly, right ? – anthares Mar 02 '10 at 13:17
  • 2
    They wanted to be *explicit* about not falling through. The required `break` statement is a *declaration* that the code will not fall through. – Robert Harvey Mar 02 '10 at 13:18
  • @RobertHarvey: Because fall-through _is_ allowed if the statement is empty. – Sebastian Mach Sep 14 '15 at 08:23
  • @phresnel: Technically, that's not fallthrough; it's just multiple labels on the same statement. – Robert Harvey Sep 14 '15 at 15:34
  • @RobertHarvey: Technically, if I jump to a label, then fall through to the next `case`-label for a lack of `break`, I'd consider it fall-through. More technically, falling through is simply the lack of a jump-instruction, e.g. `break`. – Sebastian Mach Sep 15 '15 at 10:10
  • @phresnel: "Falling through" to another label with no code in between is not important to this particular conversation, regardless of what you call it. Everyone agrees that that kind of "fall-through" is non-controversial. – Robert Harvey Sep 15 '15 at 16:56
2

Fallthrough is allowed if the case expression is empty:

case Foo:  // fallthrough allowed.
case Bar:
    Console.WriteLine ("Foo or Bar");
    break; // required

That it is not allowed is a common misconception in the same league as "you can't assign values in if-conditions" *


* You can. The rule is just that only boolean values are allowed in if-conditions, and x=false with bool x; is a boolean value.

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
0

Usually this kind of code is a bug:

// Contrived calculator demostration
decimal x = 5m;
decimal y = 10m;
decimal result = 0m;
string blah = "Divide";

// .. other code omitted

switch(blah) {
    case "Divide":
        result = x / y;

    case "Multiply":
        result = x * y;

    case "Add":
        result = x + y;

    case "Subtract":
        result = x - y;

    default:
        MessageBox.Show("Not a valid operation");

}

However, the compiler can't assume the missing breaks are a bug. As far as it knows, you really did want the cases to fall-through.

Simply assuming that breaks should be at the end of every case would just trade one bug for a different bug.

So, instead, the language designers disallowed fall-through from non-empty cases and throw an error if you omit them.

If you need code shared between non-empty cases, put it in a private (possibly static) method and call it from there.

One last note: Empty cases falling through is all that an empty case is expected to do, which is why it's allowed.

Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • Actually the question was why language designers throw an error, instead of just implicitly break your case after it's done. – anthares Mar 02 '10 at 15:18
  • 1
    But "The compiler can't assume the missing breaks are a bug." only because it is written this way. Since the fall-through in non empty cases is not allowed the question is way the compiler throws an error instead assume the only one allowed behavior. – anthares Mar 02 '10 at 15:27
  • the compiler can't assume the missing breaks are a bug. As far as it knows, you really did want the cases to fall-through. Simply assuming that breaks should be at the end of every case would just trade one bug for a different bug. – Powerlord Mar 02 '10 at 15:27
  • You can explicitly "fall-through" with a `goto case` statement: http://msdn.microsoft.com/en-us/library/13940fs2.aspx – Sam Harwell Mar 02 '10 at 15:29
  • But this is different case. It is an instruction that will be executed before the end of the case. So, it will not mess with the proposed by me logic - "if reach the end of the case, put a break". – anthares Mar 02 '10 at 15:33