2

why the code inside the if block executed any way?

switch(v)
{
case a:
    break;
...
if(condition)
{
    case f:
        ...
        break;
    case g:
        ...
        break;
}
...
case z:
    ...
    break;
default:
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169
MTVS
  • 2,046
  • 5
  • 26
  • 37
  • 1
    Because the conditional branch is never executed. Control flow never reaches your `if(condition)` line. – leemes Jan 14 '13 at 15:25
  • Perhaps because `switch` can jump to any `case` inside, but more code is necessary. – zch Jan 14 '13 at 15:27
  • 3
    It's quite a long time since I saw such a weird and unintuitive code like this last time. – LihO Jan 14 '13 at 15:28
  • Is this code you found somewhere, or something that you want to accomplish? – Mr Lister Jan 14 '13 at 15:30
  • @MrLister I wanted the cases inside the "if block", considered if the condition were true, they are options of a menu, i wanted that those options just considered when a certain situation is true. – MTVS Jan 14 '13 at 15:37
  • OK, go with Veger's solution then. – Mr Lister Jan 14 '13 at 15:38
  • An example of a similar construct that has actually been used: [How does Duff's device work?](http://stackoverflow.com/questions/514118/how-does-duffs-device-work) – Bo Persson Jan 14 '13 at 15:40

6 Answers6

9

The C++ compiler uses a lookup table or direct branches to the case-statements. Ignoring your the if-statement. Due to the break it is also not reached from case a.

Long answer short you cannot 'turn off' case-statements using this method.

Instead you'd need something like this:

switch(v) {
  case a :
    break;
  //...
  case f :
    if(condition) {
      //...
    }
    break;
  case g :
    if(condition) {
      //...
    }
    break
  //...
  case z :
    break;
}
Veger
  • 37,240
  • 11
  • 105
  • 116
2

A case label, as the name implies, is an actual label and works very similar to a goto label: the execution thread just jumps to it. It does not matter what structure it is in, unless that structure is another, nested switch statement.

It works the same way as this:

if (v == f)
    goto f_label;

if (condition) {
    f_label:
    // ...
}

The execution thread will jump to the f_label: label regardless of whether condition is true or not. switch labels work the same way.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
1

The case clauses for a switch are quite flexible and you can do some hacks for them. I have seen some people use switch to break out of nested for loops for instance. Still in the example above if v is f or g the switch will just skip the if statement and the code in the case will be executed right after switch.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
1

When program is compiling switch builds some table to jump from one case to another. This jumps somehow ignoring other conditional operations. BTW according to such behavior switch is faster than long if-else blocks.

triclosan
  • 5,578
  • 6
  • 26
  • 50
1

I think the best answer to how is( inspired from the answer of Nikos C.):

switch(v)
{
case a:
    break;

case z:
    ...
    break;
default:
    if(condition)
    {
        switch(v)
        {
        case f:
            ...
            break;
        case g:
            ...
            break;

        default:
            //former default
        }

    }
    else
        //former default
}
MTVS
  • 2,046
  • 5
  • 26
  • 37
  • +1, best solution since the condition only appears once and it is correct (in contrast to if/else around two separate switches). – leemes Jan 14 '13 at 16:14
0

Switch jumps to the matched case ignoring all statements in between. You have two ways to accomplish what you intend to do (depending upon the number of cases you have to implement):

Method 1 for more number of cases under the if conditional

  if(condition) {
  switch(v) {
  case f :
    ....
    break;
  //...
  case g :
    ....
    break;
  //...
  case z :
    break;
}


  switch(v) {
  case a :
    ....
    break;
  //...
}

Method 2 for less cases under the if conditional

    switch(v) {
  case a :
    break;
  //...
  case f :
    if(condition) {
      //...
    }
    break;
  case g :
    if(condition) {
      //...
    }
    break
  //...
  case z :
    break;
}
FirstName LastName
  • 1,891
  • 5
  • 23
  • 37
  • The first method isn't correct. If the condition is true, `case a` should also be considered, but in your code, it isn't. – leemes Jan 14 '13 at 16:12