3

I have a switch statement in my C++ code, and want to declare and use a variable inside a case of that statement. The variable will only be used inside the scope of that particular case.

switch(mode)
{
case abc:
    ...
    struct commonData;
    commonData = manager->getDataByIndex(this->Data.particularData);
    int someInt = 1;
    ...
    break;
case xyz:
    ...
    commonData = Manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

I tried simply declaring, initialising and using the variable (int someInt) just inside that case, but this gave me a few compile errors... Having come across this question on SO: Why can't variables be declared in a switch statement?, I tried doing what the answer suggested, and added {} to the case in question, so my switch now looks like this:

switch(mode)
{
case abc:
    {
    ...
    struct commonData;
    commonData = manager->getDataByIndex(this->Data.particularData);
    int someInt = 1;
    ...
    break;
    }
case xyz:
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

But I'm now getting compile errors that say: "undeclared identifier" on a variable (commonData) that is used inide the xyz case of the switch.

Having had a look into this- it seems that this variable is declared inside the abc case of the switch... So obviously, since I have added the {} to abc, by trying to use it outside abc, I am now trying to use it outside the scope of its declaration.

So why is it that I can't declare/ use someInt in the same way as commonData has been declared/ used without the need for the {} inside the case where it's declared?

Community
  • 1
  • 1
Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118
  • struct TypeNameforStruct{ // struct members}; TypeNameforStruct commonData; ? – 911 May 07 '15 at 15:28
  • 2
    Huh? There is something off or incomplete with the code you posted. struct commonData does not declare a variable, but an incomplete type. – Avi Berger May 07 '15 at 15:31

4 Answers4

9

{ .. } creates a local scope, so your variable declaration won't be visible in the other one.

Add a declaration to each case with local scope, or, if you want to use the variable outside the switch statement, declare it before the switch.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • Cheers- just thought of this. I don't want to use the variable outside the switch, but it seems it needs to be declared outside the switch so that it can be used inside just the one case. – Noble-Surfer May 07 '15 at 15:32
  • 2
    That's not the case. You can create local scope in the switch, and add (and *use*) a variable only to that scope. But that's not what you're doing in your example. – Karoly Horvath May 07 '15 at 15:38
4

The reason why some variable declarations are not allowed in a switch statement is: it is illegal for switch-based control flow to jump over a variable initialisation.

In your case, I assume the type of commonData has trivial initialisation (no constructor and no non-trivial members), so declaring it is perfectly fine, as would be declaring just int someInt;. However, int someInt = 1; is not allowed, since the initialisation would be skipped whenever mode is not abc.

I can't quite see what you'd get from declaring commonData only once, except for saving some typing at the cost of obscuring the code ("where did commonData come from?" when reading a case block), which is never a good trade. So I would just use {} inside each case "block" and declare commonData in each one which needs it. Or declare commonData above the switch.

But if you really want the same commonData to be shared by all cases and yet local to the switch block, you can fine-tune the scopes. Something like this:

switch(mode)
{
    SomeType commonData;
case abc:
    {
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    int someInt = 1;
    ...
    break;
    }
case xyz:
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

or this:

switch(mode)
{
case abc:
    SomeType commonData;
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    {
    int someInt = 1;
    ...
    break;
    }
case xyz:
    ...
    commonData = manager->getDataByIndex(this->Data.particularData);
    break;
default:
    ...
    break;
}

But please, think of the next maintainer, and don't play such tricks.


The answer above assumes struct commonData; is actually a "typo" in your code: literally, it would forward-declare a type, and not declare a variable. But that matches neither usage in the rest of your code, nor the text of your question, so I took the liberty of fixing this.

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
-1

Use brackets. Example:

switch (int number) {
    case 3: { 
        int n = 5; 
        n = n*4; // random
    } break;

    case 4: {
        int a = 4;
        //  n is out of scope
    } break;
};
Evan Carslake
  • 2,267
  • 15
  • 38
  • 56
-1

The binary code order of switch statement might be different than the orignal code because compiler would optimize the code into a binary-search tree. Thus the cross scope variables are not allowed.

jayatubi
  • 1,972
  • 1
  • 21
  • 51