Local scale in the switch enclosure

I saw an unexpected code:

#include <iostream>
using namespace std;

int main() {
    // your code goes here
    auto myDummy = [](int i){
    switch(i){
        case 0: return 0;
        case 1:{
            std::cout << "Evaluated 1\n";
            if(i == 1){
                return 1;
            }
            case 2:
            std::cout << "Evaluated 2\n";
            return 2;
        }
        break;
        default: return -1;
    }
    };
    std::cout << myDummy(1) << "\n";
    return 0;
}

It compiles and runs without warning. The bracket of case 1 {} seems to be ignored.

myDummy (1)

-> 1

myDummy (2)

-> 2

If I change the code for case 1 as follows:

             case 1:{
                std::cout << "Evaluated 1\n";
                int a = i;
                if(a == 1){
                    return 1;
                }
                case 2:
                std::cout << "Evaluated 2\n";
                return 2;
            }
            break;

then it no longer compiles:

prog.cpp: 16: 13: error: jump to case label [-fpermissive]

    case 2:

         ^ prog.cpp:12:21: note:   crosses initialization of 'int a'

             int a = i;

Brackets for case 1: {} break; will not undo the switch context. It just creates a local scope for the variable. But this is really confusing. Why is this behavior?

+4
source share
3 answers

This standard says switch(§6.4.2, emphasis mine):

2 - case : -: - ( 5,19 ) .

<... >

5 - , . , , case

, switch , , :

int main() {
    int i = 0;
    switch(i)
    {
        case 1:
        {
        case 2:
            {
                if(false)
                {
                    case 0:
                        std::cout << "hello there!"; //yes it will print
                }
            }
        }
    }

    return 0;
}

, , .

case 1:{
    std::cout << "Evaluated 1\n";
    int a = i;
    if(a == 1){
            return 1;
    }
    case 2:
    //here a is in scope
    std::cout << "Evaluated 2\n";
    return 2;
 }

case2 a, a - .

+3

:

int main() {
    int a;
    {
        int a; // in a more local scope.
    }
}

, 2 :

int main() {
    int b;
    switch(1) {
    case 0:
        int a = 0; // error
        break;
    case 1:
        b = a; // what happens?
        break;
    }
}

, case ( , ):

int main() {
  switch(1) {
  case 1: {
    break;
  case 2:
    break;
    }
  }
}
+2

switchLabel works identically with Label gotowhen it comes to moving to another block of a region.

You should take care of adopting such a scheme, in particular with respect to reading uninitialized variables whose behavior is undefined.

+2
source

Source: https://habr.com/ru/post/1612568/


All Articles