Ответ 1
На самом деле есть 2 вопроса:
1. Почему я могу объявить переменную после метки case
?
Это потому, что в С++ метка должна быть в форме:
N3337 6.1/1
меченый-оператор:
...
- атрибут-спецификатор-seqopt
case
constant-expression
:statement
...
И в заявлении объявления C++
также рассматривается как оператор (в отличие от C
):
N3337 6/1:
утверждение:
...
- декларация-выражение
...
2. Почему я могу перейти через объявление переменной, а затем использовать его?
Потому что: N3337 6.7/3
Можно передать в блок , но не таким образом, чтобы обходить объявления с инициализацией. программа, которая прыгает ( передача из условия оператора оператора на ярлык case рассматривается как прыжок в этом отношении.)
из точки, где переменная с продолжительностью автоматического хранения не находится в области до точки, где она находится в области, неформатирована , если переменная не имеет скалярный тип тип класса с тривиальным значением по умолчанию конструктор и тривиальный деструктор, cv-квалифицированная версия одного из этих типов или массив одного из предшествующих типов и объявляется без инициализатора (8.5).
Так как k
имеет скалярный тип и не инициализируется в точке объявления, прыгающей через него, то объявление возможно. Это семантически эквивалентно:
goto label;
int x;
label:
cout << x << endl;
Однако это не сработает, если x
был инициализирован в точке объявления:
goto label;
int x = 58; //error, jumping over declaration with initialization
label:
cout << x << endl;