string in swtich case

hi

I wonder why when i use string in swtich statement for example:
1
2
3
4
5
6
7
int i =1;
switch (i)
{
case 1: string name;
cin>> name;
cout << name;
break;


i get an error message like this:

initialization of 'name' is skipped by 'case' label
see declaration of 'name'


i figured out that all i have to do is to put opening curly bracket after case 1: and closing after break and it work fine.. but why.
what is the problem and is there any other way to prevent of error??

thanks :)
closed account (Dy7SLyTq)
i remember being told something about when you use objects in a switch you have to use {} idk why though
The problem is the scope of the local variable. The variable name is still within scope throughout the rest of the switch statement. But if one of the other cases is executed, the variable will not have been properly constructed.

You found one solution, which is to use braces to limit the scope. The alternative would be to move the definition of the variable outside the body of the switch statement. Generally, it would be preferred to limit the scope of the variable to the part of the code where it is needed, so the first solution might be better. But the context and what the code is trying to achieve would influence the decision.
I receive the same error using Microsoft's compiler in Visual C++ 2010 when trying to compile this code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
using namespace std;

int main() {

    if(true) goto after_p;

    string p;
    cin >> p;
    cout << p;
after_p:

    return 0;
}


switch is doing the same kind of thing with a little different syntax. It is jumping to a label. Consider this coding atrocity that actually builds with my compiler:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
using namespace std;

int main()
{
    goto if_label;
    if(true)
    {
        cout << "1\n";
if_label:
        cout << "2\n";
    }

    int switcher = 4;
    switch(switcher)
    {
    case 1:
        if(true)
        {
            cout << "3\n";
    case 4:
            cout << "4\n";
        }
    default:
        break;
    }

    return 0;
}

If you're curious, the output is:
2
4


Since jumping to labels doesn't care one bit about breaching into scope, the compiler is trying to save you some grief by not letting you initialize new variables unless you contain them in a new scope or define them outside the scope of the 'goto'. This will not compile because the "case 4 label" splits the containing scope of inBetweenLabels.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string>
using namespace std;

int main()
{
    goto if_label;
    if(true)
    {
        cout << "1\n";
if_label:
        cout << "2\n";
    }

    int switcher = 4;
    switch(switcher)
    {
    case 1:
        if(true)
        {
            int inBetweenLabels = 3;
            cout << "3\n";
    case 4:
            cout << "4\n";
        }
    default:
        break;
    }

    return 0;
}


http://msdn.microsoft.com/en-us/library/s6s80d9f%28v=vs.100%29.aspx
Last edited on
thanks folks

it had been really helpfull. at least now i know why it is so. but then other question pops up in my mind. why it doesn t complain when i use char inside of switch statement. thank you. :)
You'd need to give an example of how you are using char.

I tried this in two different compilers, both gave an error.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

using namespace std;

int main()
{
    int num = 4;

    switch (num)
    {
        case 1:
            char a = 'W';
            cout << a << endl;
            break;
            
        case 4:
    
        default:
            break;
    }

    return 0;
}
closed account (Dy7SLyTq)
@chervil: i thought it was only for objects
The problem is initialization. This compiled for me, and all I did was remove the initialization (not the declaration):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

using namespace std;

int main()
{
    int num = 4;

    switch (num)
    {
        case 1:
            char a;
            cout << a << endl;
            break;
            
        case 4:
    
        default:
            break;
    }

    return 0;
}

I suspect it may be working because there is not an initialization step in mirec's code with char.
Last edited on
That makes sense. A std::string has initialisation which always takes place, unlike primitive types such as int or char.
Last edited on
Haha, this builds:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

using namespace std;

int main()
{
    int num = 4;

    switch (num)
    {
        case 1:
            char a;
            a = 'W';
            cout << a << endl;
            break;
            
        case 4:
    
        default:
            break;
    }

    return 0;
}


This doesn't:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

using namespace std;

int main()
{
    int num = 4;

    switch (num)
    {
        case 1:
            char a = 'W';
            cout << a << endl;
            break;
            
        case 4:
    
        default:
            break;
    }

    return 0;
}


I'm getting into a place where I don't know the standard well enough to say what is expected behavior or what may be compiler-specific and non-conforming. Weird stuff, guys. Avoid the pothole and create new scope, I guess!

From MSDN:
You cannot jump past a declaration with an initializer unless the declaration is enclosed in a block.
Last edited on
thank you guys that makes lot more sense to me now. appreciate it :)
You can read also my answer in the following thread

http://www.cplusplus.com/forum/beginner/96208/
Last edited on
thanks vlad... :)
Topic archived. No new replies allowed.