Почему нельзя объявить переменные в операторе switch? - PullRequest
8 голосов
/ 16 января 2009

Я хочу узнать больше о " Почему переменные не могут быть объявлены в операторе switch? "

Я прочитал пост, но точно не понял. Вы можете просто объявить переменную внутри switch, но для того, чтобы объявить переменную и инициализировать переменную или объявить объект класса, это дает ошибку времени выполнения.

Пожалуйста, объясните мне ....

Ответы [ 2 ]

20 голосов
/ 16 января 2009

По сути, потому что инициализация переменной будет пропущена, если метка, содержащая инициализацию переменной, не будет нажата. Это было бы плохо, потому что компилятор должен был бы тогда испускать код, который разрушил бы упомянутую переменную, если и только если код инициализации был выполнен.

Например:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    A a;
    break;
  default:
    // do something else
}

Если бы код набрал default, то a не было бы инициализировано. Компилятор должен был бы быть в состоянии выяснить это заранее. Вероятно, по соображениям производительности это было запрещено.

Простое решение состоит в том, чтобы ввести новый уровень области действия:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    {
      A a;
    }
    break;
  default:
    // do something else
}

Теперь все в порядке, разрушение a теперь четко определено.

8 голосов
/ 16 января 2009

Здесь существует конфликт между синтаксисом языка и здравым смыслом. Для нас, людей, похоже, что этот код (взят из ответа 1800 INFORMATION) должен работать нормально:

class A
{
  // has some non-trivial constructor and destructor
};

switch (x)
{
  case 1:
    A a;
    break;
  default:
    // do something else
}

В конце концов, фигурные скобки определяют область действия для a ; он создается только в том случае, если мы введем case 1 , он уничтожается сразу после выхода из блока case 1 и никогда не будет использоваться, пока мы не введем case 1 . На самом деле метки case и инструкция break не разделяют области, поэтому впоследствии a существует во всем блоке, даже если он логически недоступен. И, конечно же, с синтаксической точки зрения нет такого понятия, как case 1 block.

Если вы рассматриваете оператор switch как набор (структурированных) goto скрытых инструкций, проблема области видимости становится более очевидной:

{
  if (x == 1)
    goto 1;
  else
    goto default;

  1:
    A a;
    goto end;

  default:
    // do something else

  end:
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...