3
  1. Why is declaring + initializing a variable inside a case of a switch statement not allowed & gives an error, but if it is declared it on one line then assigned a value on another, it compiles?
  2. Why the variable that was declared in a previous case can be used(operated on) in another matching case even if the previous case statements did not execute!

This code compiles with no errors or warnings:

char ch; cin>> ch;
switch(ch)
{
    case 'a':
        int x;  // How come this is ok but not this(int x = 4;)?
        x = 4;
        cout<< x << endl;
        break;
    case 'b':
        x += 1;  // x is in scope but its declaration did not execute!
        cout<< x << endl;
        break;
    case 'c': 
        x += 1;
        cout<< x << endl;
        break;
}

I expected case 'b' Or case 'c' to not know that there is a variable called x. I know the variable is still in scope in case b and case c.

case 'a' prints 4

case 'b' prints 1

case 'c' prints 1

Edit: No the other question thread that is marked as a possible duplicate does not answer my question.

  1. why is the variable x can not be defined and initialized? what problems would that create that it is not allowed to do so?

If it is allowed to define the variable only in one statement, then the variable gets used in the matching case and whatever garbage was in there gets used; so what difference does it make from declare + initializing the value?

topcat
  • 177
  • 3
  • 17
  • 2
    Why did you tag your question both C and C++? They're very different languages and this does not compile as C, even without the `cout` stuff. The first commented line is a constraint violation in C. – R.. GitHub STOP HELPING ICE May 23 '19 at 03:50
  • Declaring in `switch` alone is not allowed, but declaring within separate scopes created in a `switch` is fine in C. e.g. `switch(ch) { case 'a': { int x; .. } case 'b' : ... }` – David C. Rankin May 23 '19 at 03:54
  • @R..: I believe it's a syntax error in C. Since `int x;` is a declaration and not a statement, `case 'a': ...` doesn't satisfy the syntax of a labelled statement. (But it can be made legal by adding a semicolon after `case 'a':`.) – Keith Thompson May 23 '19 at 03:54
  • @KeithThompson: OK, actually a syntax error, which I was thinking of as a type of constraint violation but it's probably not formally even that. :-) – R.. GitHub STOP HELPING ICE May 23 '19 at 03:57
  • Seems reasonable. `int x;` is a declaration and x becomes visible in the switch statement. OTOH, doing something with x is a function of what path is taken. So combining declaration and initialization could be misleading. Would initialization only occur if the path was taken? So not allowing it makes sense. – doug May 23 '19 at 03:57
  • @R.. yeah, I removed the C tag. – topcat May 23 '19 at 03:58
  • 1
    Possible duplicate of [Why can't variables be declared in a switch statement?](https://stackoverflow.com/questions/92396/why-cant-variables-be-declared-in-a-switch-statement) – Hong Ooi May 23 '19 at 04:05
  • @HongOoi no, it does not answer my question. – topcat May 23 '19 at 04:08
  • 1
    @topcat actually it does (although not the first one): https://stackoverflow.com/a/19830820/1753435 – andreee May 23 '19 at 06:24

1 Answers1

4

The case label functions as a target of a goto statement.

The C++ standard states in [stmt.dcl]/3:

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization.

So the below will fail:

case 'a':
    int x = 4; //will fail

whereas the following will not fail:

case 'a':
    int x;  // this is ok 
    x = 4;

In response to the OP's edit:

In this particular case, just the declaration makes x visible throughout the switch statement as there are no braces {} surrounding it. So x can be used in with the other cases as well although the compiler will warn about using it uninitialized. Note that reading of an uninitialized variable is undefined behavior.

To answer the last part of your question:
Suppose the declaration with initialization was allowed it would mean that that particular value of x (4 in this case) would have to be used in other cases as well. Then it would seem as if code for multiple cases was executed. So this is not allowed.

P.W
  • 26,289
  • 6
  • 39
  • 76