switch-case statement without break
Asked Answered
L

8

39

According to this book I am reading:

Q What happens if I omit a break in a switch-case statement?

A The break statement enables program execution to exit the switch construct. Without it, execution continues evaluating the following case statements.

Suppose if I have codes looking like

switch (option}{
    case 1:
    do A;
    case 2:
    do B;
    default:
    do C;
    break;
}

Does this mean if I choose case 1, the A and C are done. If I choose case 2, B and C are done. If i choose neither, then only C is done.

if so, what happens if we omit the break after do C.

I assume these are bad programming practice, but I am curious what would happen to get a deeper understanding how it all works. Thanks

Lumpy answered 19/10, 2015 at 19:34 Comment(9)
"if I choose case 1, the A and C are done": No A, B and C is done.Precursor
Just compile some test code that does this and you'll find out I guess :pRipp
You execute everything starting from the selected case up until you see a break or the switch statement ends. So it might be that only C is executed, or B and then C, or A and B and C, but never A and C.Ygerne
BTW this is not bad programming practice.Precursor
Obligatory reference to Duff's Device :)Euromarket
Even if you omit the break after "do C", there is no difference in the execution of the code.Deflected
Good practice would be to annotate those missing breaks with e.g. [[clang::fallthrough]], or at least leave a comment. Otherwise everyone thinks there must be a bug (as is the case most of the time).Dipeptide
@101010 but if we have case 1, then it won't be case 2 at the same time. It will check whether option==2 but it will not do B if it did AChelate
@Ygerne I'm confused by your comment: "You execute everything from the selected case up". Shouldn't that be "You execute everything from the selected case down"?Toadflax
W
10

The break acts like a goto command. Or, as a better example, it is like when using return in a void function. Since it is at the end, it makes no difference whether it is there or not. Although, I do like to include it.

Weinhardt answered 19/10, 2015 at 19:45 Comment(7)
I suspected this after the comments left beneath the questions. This is a good explanation, thanks.Lumpy
Hm, I think emphasizing the GOTO-like nature of break is important.Obmutescence
@Kyle Strand I was thinking it might be better described as a return in a void function because of the scope.Weinhardt
@craigmosey Hm, I think what I meant is that it's important to realize that the switch itself is like a GOTO, because the individual cases are not separate scopes (unless you explicitly add a scope). So unlike functions, there is no automatic setup or cleanup on entering/exiting a case.Obmutescence
@ Kyle Strand ahhh, didn't know there was no clean up, figured because the switch case as a whole has its own scope, it would clean up. so basically the switch case as a whole does not clean up on exit and acts just like a bunch of goto's. Although it, as a whole, does have its own scope.Weinhardt
It would be nice that the accepted answer covers all aspects of the OP. Especially, it should be edited to point out that in case 1, A, B and C will all be executed, not only A and C.Greer
Grim reaper here bringing the issue from the grave: this is plain wrong. See CPP refference en.cppreference.com/w/cpp/language/switch if there is no break code contained in all further cases is just run as each case was true. In provided example specyfying 1 as input yields A B C; 2 yields B, C; any other value yields CPretoria
M
54

You execute everything starting from the selected case up until you see a break or the switch statement ends. So it might be that only C is executed, or B and then C, or A and B and C, but never A and C

Memorize answered 19/10, 2015 at 19:37 Comment(1)
why is the behaviour such though? why does it simply ignore further conditions if it matches case once?Citarella
F
20
  • If you don't include break in any of case then all the case below will be executed and until it sees break.

  • And if you don't include break in default then it will cause no effect as there are not any case below this 'Default' case.

  • And not using break generally considered as a bad practice but some time it may also come handy because of its fall-through nature.For example:

    case optionA:

    //optionA needs to do its own thing, and also B's thing.
    //Fall-through to optionB afterwards.
    //Its behaviour is a superset of B's.
    

    case optionB:

    // optionB needs to do its own thing
    // Its behaviour is a subset of A's.
    break;
    

    case optionC:

    // optionC is quite independent so it does its own thing.
    break;
    
Fussell answered 19/10, 2015 at 19:39 Comment(0)
W
10

The break acts like a goto command. Or, as a better example, it is like when using return in a void function. Since it is at the end, it makes no difference whether it is there or not. Although, I do like to include it.

Weinhardt answered 19/10, 2015 at 19:45 Comment(7)
I suspected this after the comments left beneath the questions. This is a good explanation, thanks.Lumpy
Hm, I think emphasizing the GOTO-like nature of break is important.Obmutescence
@Kyle Strand I was thinking it might be better described as a return in a void function because of the scope.Weinhardt
@craigmosey Hm, I think what I meant is that it's important to realize that the switch itself is like a GOTO, because the individual cases are not separate scopes (unless you explicitly add a scope). So unlike functions, there is no automatic setup or cleanup on entering/exiting a case.Obmutescence
@ Kyle Strand ahhh, didn't know there was no clean up, figured because the switch case as a whole has its own scope, it would clean up. so basically the switch case as a whole does not clean up on exit and acts just like a bunch of goto's. Although it, as a whole, does have its own scope.Weinhardt
It would be nice that the accepted answer covers all aspects of the OP. Especially, it should be edited to point out that in case 1, A, B and C will all be executed, not only A and C.Greer
Grim reaper here bringing the issue from the grave: this is plain wrong. See CPP refference en.cppreference.com/w/cpp/language/switch if there is no break code contained in all further cases is just run as each case was true. In provided example specyfying 1 as input yields A B C; 2 yields B, C; any other value yields CPretoria
I
8
switch (option}{
    case 1:
    do A;
    case 2:
    do B;
    case 2:
    do C;
    break;  
    default:
    do C;
}

if your option is 1 it executes everything til it finds the break keyword... that mean break end the excution of the switch --> case Output :A then B then C so it is recommended to put break after each case like :

switch (option}{
        case 1:
        do A;
        break;
        case 2:
        do B;
        break;
        do C;
        break;        
        default:
        do D;
    }

if your option is 1 the Output will be : just A ...

note: default doesn't need a break;

Ils answered 19/10, 2015 at 19:48 Comment(0)
G
4

I've seen in many comments and answers that it's a bad practice to omit break lines. I personally find it very useful in some cases.

Let's just take a very simple example. It's probably not the best one, just take it as an illustration:
- on bad login, you need to log the failed attempt.
- for the third bad attempt, you want to log and do some further stuff (alert admin, block account, ...).

Since the action is the same for first and second try, no need to break between these two and rewrite the same commands a second time.
Now the third time, you want to do other things AND also log. Just do the other things first, then let it run (no break) through the log action of the first and second attempts:

switch (badCount) {
    case 3: //only for 3
        alertAdmin();
        blockAccount();
    case 2: //for 2 AND 3
    case 1: //for 1 AND 2 and 3
        errorLog();
        badCount++;
}

Imho, if it was soooo bad practice to have common code for different cases, the C structure would simply NOT allow it.

Greer answered 25/10, 2015 at 1:26 Comment(2)
You should use if-statements with this, not a switch. A switch is supposed to stack up unrelated cases of the value of an expression, no-one reading your code will find the vertical direction of the code to correspond to its logical direction.Haber
Then you mean no-one is able to read and understand basic samples in Microsoft online doc? learn.microsoft.com/en/cpp/c-language/… , see sample code-blocks 2 and 4.Greer
M
2

The key is execution control is transferred to the statement for the matching case. E.g.

1. switch(x) {
2.   case 1:
3.      do_step1;
4.   case 2:
5.      do_step2;
6.   default:
7.      do_default;
8.   }

Treat lines 2, 4, 6, as "Labels" for the goto calls. On x = 1, the control will be transferred to line 3 & execution of line 3, 5 & 7 will occur.

Megmega answered 1/3, 2020 at 21:45 Comment(1)
"goto calls" Good way of thinking of it. I learned something new. ThanksDavenport
V
0

Try yourself - Run the code using ideone available here.

#include <stdio.h>

void doA(int *i){
    printf("doA i = %d\n", *i);
    *i = 3;
}

void doB(int *i){
    printf("doB i = %d\n", *i);
    *i = 4;
}

void doC(int *i){
    printf("doC i = %d\n", *i);
    *i = 5;
}

int main(void) {
    int i = 1;
    switch(i){
        case 1:
            doA(&i);
        case 2:
            doB(&i);
        default:
            doC(&i);
            break;
    }
    return 0;
}

Output:

doA i = 1
doB i = 3
doC i = 4

Note:

  • It will execute all the options from the selected case until it sees a break or the switch statement ends. So it might be that only C is executed, or B and then C, or A and B and C, but never A and C
  • If you change the value of the variable analysed in switch inside the handle function (e.g doA), it does not affect the flow as describe above
Vanburen answered 4/7, 2020 at 18:2 Comment(0)
C
0

Without break statements, each time a match occurs in the switch, the statements for that case and SUBSEQUENT CASES execute until a break statement or the end of the switch is encountered.

Crowell answered 22/12, 2021 at 19:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.