First some background on how switch (really) works:
A switch is usually thought of as a construct that selects a piece of code to execute depending on the value of some expression, as in
switch (x) {
case 1:
    foo();
    break;
case 2:
    bar();
    break;
}
However, it's more accurate to think of a switch as a form of computed goto statement. For example, the following is perfectly legal:
switch (x) {
    puts("I can't be reached");
case 1:
    if (cond) {
case 2:
        puts("Either x == 1 && cond, or x == 2");
    }
}
Depending on the value of x, the program will jump to either case 1 or case 2 (or past the switch if x is neither 1 nor 2).
Your program will compile as C (with junk values for x and y inside the switch, since the initializations are skipped), but not as C++. The reason is that C++ does not allow a jump to a case label to cross the initialization of a variable. For simple types like int, skipping over int x; is allowed (since no initialization is involved), but not skipping over int x = 1;.
The main motivation for this difference is probably that letting a jump to a case label cross an initialization in C++ would be unsafe when constructors are involved. For example, if C++ allowed a case label to occur after a definition My_class my_object within some scope, then jumping to that case label would skip my_object's constructor but still run its destructor when exiting the scope.
The same restrictions apply to goto in C++. You can't use it to jump into a block and past a variable initialization.
As a side note, switch follows the same general syntax as if and while. The syntax of if as given in the C11 standard (ISO/IEC 9899:2011, section 6.8.4) is
if ( expression ) statement
, while the syntax of switch is
switch ( expression ) statement
The only difference as far as statement is concerned (in C -- C++ adds some more limitations as mentioned above) is that it is allowed to contain case labels (and break) for a switch but not for an if (unless the if occurs within a switch).
Just as with an if, you can even leave off the braces and write code like the following. (Whether this is unnecessarily confusing is another discussion.)
switch (x) case 1: case 2: puts("x is 1 or 2");
Syntactically, case and default labels belong in the same category as goto labels. Section 6.8.1 of the C11 standard has the following definition:
labeled-statement:
          identifier : statement
          case constant-expression : statement
          default : statement