Почему не хочет инициализироваться переменная внутри CASE?
От: LaFlour Австралия blog: http://spaces.live.com/laflour
Дата: 20.12.02 11:54
Оценка:
Имеем оконную процедуру, и для примера
меню с обработчиком IDM_RUN
когда внути обработки я делаю:
...
case IDM_RUN:
   int i = 10;
   break;
...


то я получаю сообщение, что
error C2361: initialization of 'i' is skipped by 'default' label


Понятно, что надо объявлять переменную выше, но объясните подробно почему
нельзя объявить внутри определенного case?
:: I'm listening "K-Pax Soundtrack — Grand Central" ::
Re: Почему не хочет инициализироваться переменная внутри CAS
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 20.12.02 11:56
Оценка:
Здравствуйте, LaFlour, Вы писали:

LF>Понятно, что надо объявлять переменную выше, но объясните подробно почему

LF>нельзя объявить внутри определенного case?

By design of C++...
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Почему не хочет инициализироваться переменная внутри CAS
От: ziserg Украина  
Дата: 20.12.02 12:00
Оценка:
Здравствуйте, LaFlour, Вы писали:

LF>Имеем оконную процедуру, и для примера

LF>меню с обработчиком IDM_RUN
LF>когда внути обработки я делаю:
LF>
LF>...
LF>case IDM_RUN:
LF>   int i = 10;
LF>   break;
LF>...
LF>


LF>то я получаю сообщение, что

LF>error C2361: initialization of 'i' is skipped by 'default' label
LF>

Помести ее в блок операторов
case IDM_RUN:
{
   int i = 10;
   break;
}
Re[2]: Почему не хочет инициализироваться переменная внутри
От: LaFlour Австралия blog: http://spaces.live.com/laflour
Дата: 20.12.02 12:08
Оценка:
Здравствуйте, ziserg, Вы писали:

Z>Здравствуйте, LaFlour, Вы писали:


Z>Помести ее в блок операторов

Z>
Z>case IDM_RUN:
Z>{
Z>   int i = 10;
Z>   break;
Z>}
Z>


А объяснение этому есть? с точки зрения компилятора?
:: I'm listening "K-Pax Soundtrack — Good Morning Bess" ::
Re: Почему не хочет инициализироваться переменная внутри CAS
От: Кодт Россия  
Дата: 20.12.02 12:16
Оценка:
Здравствуйте, LaFlour, Вы писали:

LF>
LF>...
LF>case IDM_RUN:
LF>   int i = 10;
LF>   break;
LF>...
LF>


LF>то я получаю сообщение, что

LF>error C2361: initialization of 'i' is skipped by 'default' label
LF>

LF>Понятно, что надо объявлять переменную выше, но объясните подробно почему

LF>нельзя объявить внутри определенного case?

Не "внутри", а "после"!

Потому что case — это метка.
Когда программа доходит до следующего case|default, она... продолжает начатое дело.

Соответственно, область видимости переменной — от места ее объявления до конца составного оператора.
А конец у нас — это switch() { ... }.

Аналогично, нельзя делать такой фокус
  goto A; // попытка объехать создание переменной
  ...
  int x;
  ...
A:
  ...

Особенно это критично для любых инициализируемых переменных, в том числе для объектов с конструкторами.

Хочешь изолировать — пиши
case 1:
case 2:
  {
    ...
    int x;
    ...
  }
  break;
case 3:
  ...
Перекуём баги на фичи!
Re[2]: Почему не хочет инициализироваться переменная внутри
От: ziserg Украина  
Дата: 20.12.02 12:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, LaFlour, Вы писали:


[skipped...]

К>Хочешь изолировать — пиши

К>
К>case 1:
К>case 2:
К>  {
К>    ...
К>    int x;
К>    ...
К>  }
К>  break;
К>case 3:
К>  ...
К>

Если уж очень не любишь скобки, то можешь еще вот так
case 2: 
    int x;
    x = 10; 
    ...
    break;
Re[3]: Почему не хочет инициализироваться переменная внутри
От: jazzer Россия Skype: enerjazzer
Дата: 20.12.02 14:15
Оценка: 3 (1)
Здравствуйте, LaFlour, Вы писали:

LF>Здравствуйте, ziserg, Вы писали:


Z>>Здравствуйте, LaFlour, Вы писали:


Z>>Помести ее в блок операторов

Z>>
Z>>case IDM_RUN:
Z>>{
Z>>   int i = 10;
Z>>   break;
Z>>}
Z>>


LF>А объяснение этому есть? с точки зрения компилятора?


в двух словах так:
компилятор создает вызывает конструктор в точке объявления и деструктор в точке выхода переменной из области видимости.

поскольку у тебя видимость переменной i простирается за пределы твоего case, то код для вызова деструктора будет лежать там же.
с другой стороны, конструктор у тебя вызывается в зависимости от того, попал поток в твой case или нет.
Получается, что деструктор вызывается всегда, а конструктор — иногда :), и у компилятора в общем случае нет возможности определить, когда надо, а когда — нет.
А вызывать деструктор для несконструированного объекта очень плохо.

Поэтому и нельзя.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Почему не хочет инициализироваться переменная внутри
От: VBez  
Дата: 06.02.04 12:36
Оценка:
Z>Если уж очень не любишь скобки, то можешь еще вот так
Z>
Z>case 2: 
Z>    int x;
Z>    x = 10; 
Z>    ...
Z>    break;
Z>


А с какой стати оно становится компилируемым???
Re[4]: Почему не хочет инициализироваться переменная внутри
От: Lorenzo_LAMAS  
Дата: 06.02.04 13:09
Оценка:
VB>А с какой стати оно становится компилируемым???

А с той, что инициализации при объявлении — нет.
Of course, the code must be complete enough to compile and link.
Re[5]: Почему не хочет инициализироваться переменная внутри
От: VBez  
Дата: 06.02.04 13:15
Оценка:
L_L>А с той, что инициализации при объявлении — нет.

Ай точно.
А вообще этот рудимент откудова взялся — из C?
В других языках кажется такого нету?
... << RSDN@Home 1.1.0 stable >>
Re[6]: Почему не хочет инициализироваться переменная внутри
От: Lorenzo_LAMAS  
Дата: 06.02.04 13:18
Оценка:
VB>Ай точно.
VB>А вообще этот рудимент откудова взялся — из C?
VB>В других языках кажется такого нету?

Какой рудимент? switch или что?
Of course, the code must be complete enough to compile and link.
Re[7]: Почему не хочет инициализироваться переменная внутри
От: VBez  
Дата: 06.02.04 13:23
Оценка:
L_L>Какой рудимент? switch или что?

Нет.
То, что нельзя инициализировать вот здесь:

case 0:
   int i = 10;
     break;
default:
   break;


В шарпе и джаве все классно работает.
... << RSDN@Home 1.1.0 stable >>
Re[8]: Почему не хочет инициализироваться переменная внутри
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 06.02.04 13:46
Оценка: 4 (1)
Здравствуйте, VBez, Вы писали:

VB>case 0:

VB> int i = 10;
VB> break;
VB>В шарпе и джаве все классно работает.

В шарпе case не проваливаются друг в друга (в конце обязательна передача управления), поэтому область действия переменной — внутри одного case.
Re[9]: Почему не хочет инициализироваться переменная внутри
От: VBez  
Дата: 06.02.04 13:59
Оценка:
_>В шарпе case не проваливаются друг в друга (в конце обязательна передача управления), поэтому область действия переменной — внутри одного case.
А в джаве?
... << RSDN@Home 1.1.0 stable >>
Re[3]: Почему не хочет инициализироваться переменная внутри
От: artelk  
Дата: 06.02.04 15:09
Оценка:
Здравствуйте, ziserg, Вы писали:

Z>Если уж очень не любишь скобки, то можешь еще вот так

Z>
Z>case 2: 
Z>    int x;
Z>    x = 10; 
Z>    ...
Z>    break;

Z>


А если вместо int типом x будет не встроенный тип, а пользовательский — с конструктором
по умолчанию, то проблемы с инициализацией снова возникнут.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.