Почему я не могу использовать "по умолчанию"? или "goto case x;" в структуре выбора переключателя?

Раздел 6.8.1 на C11 или C99 или раздел 3.6.1 C89 все, по-видимому, указывают, что default и case x (где x - некоторое константное выражение) являются примерами помеченных инструкций, наклейками identifier: подходят для использования с goto.

Я знаю, что я мог просто поместить метку identifier: -style непосредственно после ярлыков default: или case x:. Это не тот вопрос. Мне более любопытно, существует ли какое-либо фактическое обоснование, запрещающее такое поведение.

Если бы было возможно объявить метки default: за пределами структуры выбора switch, тогда я бы понял, так как будет некоторый конфликт между тем, где goto внутри структуры выбора switch целиться. Однако раздел 6.4.1 на C11 или C99 или 3.1.1 C89 запрещает использование default как ничего, кроме ключевого слова, а 6.8.1 ограничивает его использование далее switch только структурами (или generic структурами на C11, которые здесь неактуальны).

Я также понял бы, если многократные (возможно, вложенные) структуры switch, каждая с метками default: (или case x:) вводит двусмысленность, однако объем этих меток, по-видимому, ограничен в пределах их самого внутреннего окружения switch и ссылаясь на любой идентификатор вне его области видимости, является ошибкой, требующей диагностики во время компиляции.

Обсуждалось ли это в любых стандартных документах (например, обоснование)? Есть ли какие-либо объяснения для этого поведения, кроме "это потому, что это" или "потому что спецификация говорит так"? Если да, то какое это объяснение?

Ответ 1

(Я не вижу, как goto для case будет работать синтаксически.)

Как вы говорите, метки case и default имеют только область действия соответствующего оператора switch и могут быть переброшены только извне. С другой стороны метки в C имеют область видимости функции и могут быть перескочены из любой точки функции.

Итак, мы говорим о ярлыках с совершенно разными свойствами, они, вероятно, рассматриваются совсем по-другому, внутренне. Кажется довольно сложным примирить эти свойства и сделать реализацию этого более сложной. Внезапно вам придётся решить, при реализации goto, который case или default является правильным, тогда как теперь вам просто нужно указать адрес идентификатора области файла.

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

Ответ 2

встречный пример

fun() {
  switch (b) {
     case x:
       doSomething();
       break;
  }
  switch(b2) {
     case x:
       doMore();
       break;
  }

  goto x; // which one?
}