Ответ 1
case 0:
int foo;
В обоих языках C и С++ обозначение - это метка, за которой следует инструкция. Однако в С++ определение оператора включает в себя "объявления блока" (то есть объявления и определения, которые могут отображаться в блоке), тогда как в C это не так (в C блок представляет собой последовательность "элементов блока", которые являются либо блочными деклараций или утверждений - в С++ это последовательность операторов, которые включают объявления блоков).
case 0:
; int foo;
Это работает, потому что ;
является (n пустым) оператором как в C, так и в С++, поэтому мы действительно имеем метку, за которой следует инструкция.
case 0:
; int foo = 0;
Как уже объяснялось в комментариях, это не работает в С++, потому что С++ делает незаконным перепрыгивать через инициализацию.