2
switch (false)
{
case true:
    int jval;
    break;

case false:
    jval = 18;
    cout << jval;
    break;

}

Can anyone help me understand why I am able to access jval in this case ?

  • 10
    Because you didn't wrap your case results in {} thus defining the scope. 10001 reasons to always use {} after a case statement; number 3 – UKMonkey Feb 05 '18 at 17:35
  • 4
    That feels like a deep dark corner left over from "C". Legal, but not something I would want to see. It is visible because case statements don't define their own scope and hence we are trained to use braces. – Michael Dorgan Feb 05 '18 at 17:36
  • 3
    Didn't you get warning for that? if not, try `-Wall -Wextra` with GCC/Clang. – Nawaz Feb 05 '18 at 17:37
  • 1
    @MichaelDorgan Lookup _Duff's Device_. Nifty thing sometimes (especially with _loop unrolling_). Not really a _"dark corner"_. –  Feb 05 '18 at 17:39
  • 2
    @Nawaz None of gcc 7, clang 5 and MSVC 19 produce a warning for this unless you provide additional warnings flags. – François Andrieux Feb 05 '18 at 17:40
  • The reason why I am asking this question is because. I thought that when we reach the right cases everything before it is ignored right? – Hovhannes Vardanyan Feb 05 '18 at 17:41
  • So why the definition is visible here and not rather ignored? – Hovhannes Vardanyan Feb 05 '18 at 17:41
  • @HovhannesVardanyan Heavily related: https://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement –  Feb 05 '18 at 17:42
  • 2
    Variable declarations don't have to be executed, they're just part of the block. If it contains an initialization, that won't be done unless you execute it. – Barmar Feb 05 '18 at 17:42
  • 2
    @Nawaz why should you get a warning? Scope is defined by {} in c++; and there aren't any. This means that whatever the value of the item you're switching on, all variables in all the cases can be put on the stack. – UKMonkey Feb 05 '18 at 17:43
  • ROFL - @TheDude I've used duff's device for embedded work in the past and I would say that this is indeed a deep dark corner of the language. :) In seriousness though, it illustrates a way to get an assembly jump table effectively into C code. – Michael Dorgan Feb 05 '18 at 17:46
  • @Michael _" I've used duff's device for embedded work ..."_ Of course, same same ;-). I'd say it's a bit of black magic you can still do properly with the full compliant c++ language. It's fun to use it to program bare metal. –  Feb 05 '18 at 17:51
  • If jval were initialized in the declaration then the program would be ill-formed. – Peter - Reinstate Monica Feb 05 '18 at 18:18

2 Answers2

2

The cases are only labels, while break just means jump to the end of the switch scope block.
The lifetime of a variable is within the scope block ({ }) from the place it was declared to the closing }.

Also, if you don't put break and enter the first case statement, the program flow will pass to the next one.
So the code in the second case statement, got access to that variable.

If you want to not have access to it, guard it in another { } scope block, to limit it's life time.

Victor Padureanu
  • 604
  • 1
  • 7
  • 12
2

The variable scope is the part between curly brackets, not between case and break.
Thus, a variable declared in one case is in scope in all subsequent cases.

It may be clearer if you look at the equivalent formulation using goto:

// "Jump table"
if (false == true)
    goto case_true;
if (false == false)
    goto case_false;
goto switch_end;
// switch body begins here.
{
case_true:
    int jval;
    goto switch_end;

case_false:
    jval = 18;
    cout << jval;
    goto switch_end;
}
// switch ends here.
switch_end:

(This is more or less literally what a simple-minded compiler will translate a switch into – a sequence of jumps and a trivially transformed body.)

Note that you will get an error if you try to initialise jval:

switch (false)
{
case true:
    int jval = 13;   // Nope.
    cout << jval
    break;
case false:
    jval = 18;
    cout << jval;
    break;
}

because you're not allowed to jump across a variable initialisation.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82