-2

I don't understand why a switch-case statement requires you to explicitly insert a break after each case. Isn't the whole point of it to stop once a case is made?

Can someone give me a circumstance where a case is found true but for some reason [you insert reason here] you still need the code block to execute through.

This is a vaild PHP switch-case statement

   switch ($error) {
    case 'empty':
        $msg = 'Field cannot be empty.';
        break; 
    case 'invalid':
        $msg = "Field may only contain number.";
        break;
    }


This is a invaild PHP switch-case statement

   switch ($error) {
    case 'empty':
        $msg = 'Field cannot be empty.';
    case 'invalid':
        $msg = "Field may only contain number.";
    }


So is this break useless or does it serve a purpose in some situations?

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
MrPizzaFace
  • 7,807
  • 15
  • 79
  • 123
  • 1
    That is *not* an "invalid" switch statement, it just doesn't provide the expected results. (If `$error == 'empty'` then it will fall through to the `'invalid'` case.) – Jonathon Reinhart Nov 21 '13 at 05:13
  • Can be useful for things like state machines where one state always follows another; this way you don't have to break and re-enter the main loop (more efficient). – Dagg Nabbit Nov 21 '13 at 05:18
  • @DaggNabbit Except sometimes you explicitly *don't* want that to happen - e.g. there is other recurring logic in the loop that must execute before the next state. This is very common in VHDL state machines (where you're transitioning to the next state, but don't want to do anything until the next clock cycle). – Jonathon Reinhart Nov 21 '13 at 05:19
  • @JonathonReinhart right - not invalid in the sense of throwing an exception. But my definition of invalid means "not getting the expected outcome." – MrPizzaFace Nov 21 '13 at 05:21
  • @JonathonReinhart --- if you're going to edit out that heading, at least up-vote the question please. – MrPizzaFace Nov 21 '13 at 05:31
  • @in-spired I did not down-vote, but it's not a question worth up-voting. Sorry, but it's pretty pointless here to try and beg your way into rep. If you hover over the up-vote button you'll see `"This question shows research effort; it is useful and clear"`. That's just not the case here. – Jonathon Reinhart Nov 21 '13 at 05:32
  • @JonathonReinhart, true; ideally the state machine loop is separate from the main loop, I think. I'm imagining a sprite-based game; you could use a state machine to control which sprites render (and for how long) based on what the actor's doing -- a "hurt" state could sometimes fall through to a "die" state, for example. But the main game loop could set the state machine to any state at any time. – Dagg Nabbit Nov 21 '13 at 05:34
  • @JonathonReinhart Not begging for ANYTHING. Just asking for my headline back. Hover over downvote and it shows "this question is unclear and not useful". I disagree -- I believe a lot of people will learn and benefit from THIS question. – MrPizzaFace Nov 21 '13 at 05:35
  • @in-spired I'm certainly not going to revert my edit - it was incredibly tacky, and if anything would probably ask for further down-votes. There's a reason Stack Overflow looks so clean, and is so useful compared to your typical forum. In reality, it doesn't matter what you think about your question's quality - that's why there is a voting system. It matters what everyone else thinks. – Jonathon Reinhart Nov 21 '13 at 05:36
  • Yea well I find the down-vote "incredibly tacky" -- It's uncalled for. This wasn't a "write my code" question. Anyway, thanks for your input. Much appreciated. It's still my firm belief that 'break' is implied on a `case` match. – MrPizzaFace Nov 21 '13 at 05:39
  • I'm not sure what you're looking for, @in-spired. You asked the question: How is `case` fall-through useful? And I answered, for one, it is useful for stacking `cases` to be treated identically, as I've shown. It doesn't matter what your "firm belief" is though, sorry. That's how the language is written! If you want to change how the language works, go download the [PHP source](http://us1.php.net/downloads.php) and make the change! I'm not trying to be mean, I just don't know what you want from us. – Jonathon Reinhart Nov 21 '13 at 05:43
  • @JonathonReinhart I commented under your question. The intent of the question was to find a logical use for why the language is written as it is. Stacking `cases` like you say doesn't justify it for me. No hard feelings. I'm not trying to be mean either. – MrPizzaFace Nov 21 '13 at 05:47

4 Answers4

5

Because that's just how it works - it's how the language was designed. Probably because that's how C did it.

The most common use is for two cases to be treated the same.

switch ($error) {
   // Treat warnings and errors the same
   case 'warning':
   case 'error':
      echo "Something went wrong.";
      break;
}
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • Each `$error` is different. That's not the question. Why does your code block explicitly require a `break`? – MrPizzaFace Nov 21 '13 at 05:13
  • I understand "that's how it works" but I'm asking why couldn't it work the same, without the `break` tag. It just seems logical that `break` is implied on a `match`. – MrPizzaFace Nov 21 '13 at 05:14
  • To be fair - I think: "because thats just how it works" is actually the most accurate answer although @Michael Burr adds some context below about why it has persisted in C-based languages – hammus Nov 21 '13 at 05:14
  • @in-spired Because if the `break` wasn't required, then you **couldn't do** what I've shown above! – Jonathon Reinhart Nov 21 '13 at 05:17
  • @JonathonReinhart I disagree. A `case` whether made at `warning` or `error` is made -- hence break should be implied once a case is made. – MrPizzaFace Nov 21 '13 at 05:24
  • @in-spired You're missing my point. If `break` were implied at the end of every `case`, you **could not do** what I have written above, without duplicating code. Please, try. – Jonathon Reinhart Nov 21 '13 at 05:27
  • @JonathonReinhart sure you could. I'm not saying `break` should be implied at the end of each `case`. **I'm saying `break` should ONLY be implied if the `case` match == true** – MrPizzaFace Nov 21 '13 at 05:43
  • @in-spired Let's say `break` was implied at the end of each case. What would happen if my code was executed with `$error == 'warning'`? Remember, you added an implied `break` after each case, which means there is one before `case 'error'`. – Jonathon Reinhart Nov 21 '13 at 05:44
  • Think of it like this if a match is made on a `case` Whatever is in that `case` block is what would `break` on. I'm suggesting this kind of flow `switch`-`{case, case, case, $msg, -implied break-}`-`{case, case, $msg, -implied break-}` --- Do you understand my point? I realize that's not how it works. But theoretically, why couldn't it be that way? – MrPizzaFace Nov 21 '13 at 05:52
  • Sure I agree that it *could* work that way. It could also work any other infinite number of ways, like Python, where there is no switch statement at all. The point is *this is how PHP works*. You would break millions of applications by changing it. So what else is there to say?! – Jonathon Reinhart Nov 21 '13 at 05:56
  • Yeah kind of got off track. I just hate having to type `break`. You did provide the best answer. Thank you. – MrPizzaFace Nov 21 '13 at 05:58
  • You also just increased the complexity of the language's grammar. Now the `break` is implied, *unless there is no code, and the next line is a `case`*. – Jonathon Reinhart Nov 21 '13 at 05:58
  • Take a look at [switch statements in C#](http://msdn.microsoft.com/en-us/library/06tc147t.aspx). The `break` is still required, but implicit fall-through is disallowed - you must include an explicit `goto other-case`. – Jonathon Reinhart Nov 21 '13 at 05:59
  • Consider this: Instead of thinking of the body of each `case` statement like a `{ block-of-code; }`, think of them as labels, and the `switch` is just performing a `goto` for you. In that mentality, the `break` just makes sense. The next `case` isn't the *end* of the previous one, it's *only* where the next section of code begins. – Jonathon Reinhart Nov 21 '13 at 06:01
  • Thanks, I'll check it out. Just based on your comment though, sounds repetitive and obnoxious. (Maybe they have a good reason) --Thanks again Jonathon. – MrPizzaFace Nov 21 '13 at 06:02
  • Their reason is to prevent the "forgotten `break`" bugs, without making the language behave drastically different from the rest of the C-like languages. The only way you could make this grammar make sense, is to require the body of a `case` be a legitimate block: `case 1 { statement; statement; } case 2 { statement; statement; }` – Jonathon Reinhart Nov 21 '13 at 06:02
1

I believe this question is a duplicate to this one, answered robustly by @Micahel Burr :

Many answers seem to focus on the ability to fall through as the reason for requiring the break statement.

I believe it was simply a mistake, due largely because when C was designed there was not nearly as much experience with how these constructs would be used.

Peter Van der Linden makes the case in his book "Expert C Programming":

We analyzed the Sun C compiler sources to see how often the default fall through was used. The Sun ANSI C compiler front end has 244 switch statements, each of which has an average of seven cases. Fall through occurs in just 3% of all these cases.

In other words, the normal switch behavior is wrong 97% of the time. It's not just in a compiler - on the contrary, where fall through was used in this analysis it was often for situations that occur more frequently in a compiler than in other software, for instance, when compiling operators that can have either one or two operands:

switch (operator->num_of_operands) {
     case 2: process_operand( operator->operand_2);
               /* FALLTHRU */

     case 1: process_operand( operator->operand_1);
     break; } 

Case fall through is so widely recognized as a defect that there's even a special comment convention, shown above, that tells lint "this is really one of those 3% of cases where fall through was desired."

I think it was a good idea for C# to require an explicit jump statement at the end of each case block (while still allowing multiple case labels to be stacked - as long as there's only a single block of statements). In C# you can still have one case fall through to another - you just have to make the fall thru explicit by jumping to the next case using a goto.

It's too bad Java didn't take the opportunity to break from the C semantics.

Community
  • 1
  • 1
hammus
  • 2,602
  • 2
  • 19
  • 37
  • And thank you for the edit on your comment. Now let's delete this mess of comments! I still think this would be better as a link in a comment, but your effort is appreciated regardless. – Jonathon Reinhart Nov 21 '13 at 07:50
0

It's also used for combinatory conditions.

To give a somewhat useless example:

// manually total up a number by 1
$sum = 0;

switch ($number) {

    case 4:
       $sum += 1;
    case 3:
       $sum += 1;
    case 2:
       $sum += 1;
    case 1:
       $sum += 1;
}

This sets switch apart from exclusive if trees in that one case can be a superset of another, and reduces code duplication. If all your cases contain a break, then you can certainly transpose it into an if list. (switch is often just utilized for stylistic reasons).

mario
  • 144,265
  • 20
  • 237
  • 291
0

A single statement can carry multiple case labels, as the following example shows where we are not using break:

switch($constant)
{
    case 'a' :
    case 'b' :
    case 'c' :
    case 'd' :
    case 'e' :
    case 'f' :  hexcvt(c);
}

In this example, if constant-expression equals any letter between 'a' and 'f', the hexcvt function is called.

R R
  • 2,999
  • 2
  • 24
  • 42
  • I'm pretty sure you didn't find any PHP documentation on MSDN. Link? – Jonathon Reinhart Nov 21 '13 at 05:23
  • its a general example i gave.switch more or less works same everywhere with very few exceptions. – R R Nov 21 '13 at 05:24
  • C# does not allow fall-through (unless there is no code following a `case`), without an explicit `goto`. – Jonathon Reinhart Nov 21 '13 at 05:26
  • i know that,thats why i mentioned about 'very few exceptions'.i updated my answer.anyways the Op wants to know the use of switch without break where it can be helpful. – R R Nov 21 '13 at 05:28