Утверждение регистра в C ++: назначение меток в кросс-области? - PullRequest
0 голосов
/ 03 ноября 2010

В моем текущем коде есть ошибка, с которой я бился головой пару дней. Я опубликую краткую версию кода ниже (не мой настоящий код, но он все еще компилируется).

#include <iostream>

using namespace std;

int main()
{
  int x = 7;

  switch(x)
  {
    case 1:
    {
      case 2:
      cout << "hi";
    }
  }
}

Мне нравится иногда вводить более узкие рамки в мои случаи переключения, чтобы имена локальных переменных не мешали тем, которые я использовал ранее. По-видимому, однажды мне позвонили или что-то ответили, и я не закончил писать заявление по делу, как мне хотелось, но позже я был уверен, что у меня получилось. Случай 2 должен был быть во вложенном переключателе, а не как часть исходного внешнего переключателя (для тех, кто интересуется, я использую именованные константы в моем коде, а не просто магические числа). На g ++ я не получил предупреждение или ошибку при компиляции без каких-либо опций.

Мой вопрос: зачем разрешать перепрыжки между коммутаторами? Какую цель он служит?

Ответы [ 5 ]

4 голосов
/ 03 ноября 2010

Устройство Даффа вряд ли является «целью» кросс-кейсов, как уже предлагалось, это всего лишь его эксплуатация.

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

4 голосов
/ 03 ноября 2010

Метки случая - это просто метки, места назначения для (сгенерированных компилятором) переходов.

Так же, как обычные метки имеют область действия функции, метки регистра имеют switch область действия.

Единственное разумное преимущество - это Устройство Даффа , которое, однако, не очень актуально для современных компьютеров.

Итак, это историческая история.

Случай "замороженной истории".

Приветствия & hth.,

1 голос
/ 26 февраля 2013

Перекрестные метки регистра внутри операторов switch do служат цели, особенно в встроенных системных приложениях реального времени.С одной стороны, они позволяют более чистые реализации процедур .Они также уменьшают или исключают использование операторов goto в аналогичных приложениях низкого уровня.Да, goto ужасны, но если раньше вы писали драйверы устройств, где проблемы времени и синхронизации являются нормой, вы бы оценили полезность межсекторальных меток падежей по сравнению с высоким содержанием операторов goto.Меньшее из двух зол, если хотите.

1 голос
/ 03 ноября 2010

Этот код компилируется только по историческим причинам.

Обратите внимание, что это может привести к очень странным версиям Неопределенное поведение :

// don't try this at home
switch(x) {
  case 1:
  {
    std::string s = "hi!"
    case 2:
    cout << s; // doh!
  }
}

Если x==2, это приведет к доступу к s без предварительного вызова его конструктора. Хотя я ожидаю, что компиляторы предупредят об этом.

0 голосов
/ 03 ноября 2010

Ваш код выше является синонимом для:

switch (x)
{
     case 1:
     case 2:
     cout << "hi";
}

Компилятор не делает различий между этим кодом и кодом, который вы разместили в терминах функциональности коммутатора Это интерпретирует как несколько сценариев для инструкций.

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