tags:

views:

509

answers:

2

I want to know more about "Why can’t variables be declared in a switch statement?"

I read the post but i am not getting it exactly. You can just declare variable inside switch but to decalre and initialize a variable or to declare object of class it gives complie time error.

Please explain me....

+19  A: 

Essentially because the initialisation of the variable would be skipped if the label containing the variable initialisation was not hit. This would be bad because the compiler would then have to emit code that would destroy said variable if and only if the initialisation code had run.

For example:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    A a;
    break;
  default:
    // do something else
}

If the code had hit the default, then a would not have been initialised. The compiler would have to have been able to figure this out in advance. Probably for performance reasons, this was disallowed.

The simple fix is to introduce a new layer of scope:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    {
      A a;
    }
    break;
  default:
    // do something else
}

This makes it ok, the destruction of a is now well defined.

1800 INFORMATION
Then how do you explain gotos?
Max
Because the "goto" itself is unconditional the compiler can easily work out that you are leaving a block and drop the local varaibles of the stack before executing the goto.
James Anderson
This answer is weak. C could be have defined such that a variable declared anywhere in a block was allocated storage [and init'ed] at the top block of the block. Do we know why C has this rule? C++ relaxed the rule to declaration before use and doesn't have the problem you mention.
Tall Jeff
@Jeff: yes, C++ does have this rule. In C89, declarations must be at the beginning of a block. In C99, you can put variables anywhere, but if you jump over their decl and use them, you get undefined behaviour. You can't jump into a scope with previous variable declarations in C++.
Doug
+7  A: 

There is a conflict here between language syntax and common sense. For us humans, it looks like this code (taken from 1800 INFORMATION's answer) should work fine:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    A a;
    break;
  default:
    // do something else
}

After all, the curly braces define the scope for a; it is only created if we enter case 1, it is destroyed immediately after leaving the case 1 block and it will never be used unless we enter case 1. In fact, the case labels and the break instruction do not separate scopes, so a exists in all the block afterwards, even though it is logically unreachable. And sure, there is no such thing as a case 1 block from a syntactic point of view.

If you think of the switch statement as a bunch of (structured) goto instructions in disguise, the scope problem becomes more evident:

{
  if (x == 1)
    goto 1;
  else
    goto default;

  1:
    A a;
    goto end;

  default:
    // do something else

  end:
}
Gorpik
Thanks Gorpik I got it.
Omya
Thank you for the question, which made me think about it myself.
Gorpik