Я написал этот ответ первоначально для этого вопроса . Однако когда я закончил, я обнаружил, что ответ закрыт. Поэтому я разместил это здесь, может быть, кому-то, кому нравятся ссылки на стандартные, это будет полезно.
Оригинальный код вопроса:
int i;
i = 2;
switch(i)
{
case 1:
int k;
break;
case 2:
k = 1;
cout<<k<<endl;
break;
}
На самом деле есть 2 вопроса:
1. Почему я могу объявить переменную после case
label?
Это потому, что в C ++ метка должна быть в форме:
N3337 6,1 / 1
помечены-заявление:
...
- атрибут-спецификатор-seqopt
case
constant-expression
: statement
...
И в C++
оператор декларации также рассматривается как оператор (в отличие от C
):
N3337 6/1:
оператор
...
декларация-заявление
...
2. Почему я могу перепрыгнуть через объявление переменной и затем использовать его?
Потому что:
N3337 6,7 / 3
Возможно передать в блок, , но не так, чтобы обойти объявления с инициализацией .
программа, которая прыгает
(Перевод из условия оператора switch в метку регистра в этом отношении считается скачком .)
от точки, в которой переменная с автоматическим хранением находится вне области действия, до точки, где она находится в области действия, имеет неправильную форму , если переменная не имеет скалярного типа , типа класса с тривиальным значением по умолчанию
конструктор и тривиальный деструктор, 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;