Наличие метки случая оператора switch без значения

#c #switch-statement

#c #switch-statement

Вопрос:

Я работал с оператором Switch, когда случайно написал следующий фрагмент кода (на gcc в C)

         int a = 2;
        switch(a)
        {
                default:
                        printf("Defaultn");
                case 1:
                        printf("Onen");          
                case2 :
                        printf("Twon");
        }
  

Результат, который я получил, был:

По умолчанию

Один

Два

Я могу понять, как возник этот результат, однако я не понимаю, почему это не выдает ошибку, я имею в виду, что у меня явно нет метки случая (в случае 2), верно? Также я наблюдал тот же результат, если, например, я исправил «case2» как «casex». В то время как, если я не помещаю ни в одну метку case, это выдает ошибку времени компиляции.

Любая помощь будет оценена, спасибо!

Комментарии:

1. Не case2: выдает вам предупреждение компилятора? Ваш запрос касается отсутствия там пробела или отсутствия break ожидаемых операторов?

2. case2 является допустимой меткой; это просто не case метка с точки зрения области действия switch оператора. Без a break он просто игнорируется.

3. Предупреждение, которое я получил (от MSVC), было предупреждением C4102: ‘case2’: метка без ссылок.

4. Вы должны вставить break оператор после кода каждого case .

5. > Предупреждение, которое я получил (от MSVC), было предупреждением C4102: ‘case2’: метка без ссылок. Как упоминал Марк Беннингфилд, case2 : это «обычная» метка (для goto), а не case ключевое слово. Это предупреждение указывает goto case2; на то, что в вашей программе нет оператора … результатом здесь является case2 : не случай для вашего коммутатора, это просто метка goto внутри блока switch.

Ответ №1:

Я могу понять, как возник этот результат, однако я не понимаю, почему это не выдает ошибку, я имею в виду, что у меня явно нет метки случая (в случае 2), верно?

Да, case2 : это не метка регистра, но это допустимая действительная обычная метка. Любому оператору может предшествовать такая метка. Поскольку вы используете GCC, вы могли бы рассмотреть возможность включения этой -Wall опции (или специально -Wunused-label ), и в этом случае GCC должен предупредить, что эта метка не используется (поскольку она не является целью какого-либо goto оператора).

Также я наблюдал тот же результат, если, например, я исправил «case2» как «casex».

Ну, конечно. casex : также является допустимой обычной меткой.

В то время как, если я не помещаю ни в одну метку case, это выдает ошибку времени компиляции.

Я полагаю, вы должны иметь в виду, что вы оставляете двоеточие, но удаляете весь текст метки ( case2 / casex ). Это действительно привело бы к недопустимому коду. Однако, если вы удалили всю строку, тогда, конечно, это было бы хорошо.

Комментарии:

1. Извиняюсь, под меткой no case я имел в виду просто написание «case». Прочитав ваш ответ, я бы предположил, что, поскольку регистр является зарезервированным словом, он выдает ошибку, поскольку сам по себе он не является возможной меткой, и компилятор обрабатывает его как метку регистра переключателя и требует после нее номер.

2. Да, @KartikRamesh case зарезервировано для использования в качестве ключевого слова, поэтому case : не является ни допустимой обычной меткой, ни допустимой меткой регистра.

Ответ №2:

вы пропустили break , поэтому выполнение продолжается после каждого случая (но с a != 1, чтобы иметь эти 3 выхода)

примечание case2: рассматривается как метка (для goto), поэтому не является ошибкой

Комментарии:

1. Я думаю, OP это знает.

2. @WeatherVane ах да, я читаю быстро… на самом деле я прочитал только начало, прежде чем ответить, позор мне ^^

3. Сначала я подумал, case2 что это опечатка, но она повторяется в теле вопроса.

4. @WeatherVane да, я понимаю… когда я решил прочитать вопрос, а не только код ^^

Ответ №3:

Здесь происходит то, что вы получили метку по умолчанию, и поскольку у вас не было перерыва, вы выполнили все остальные случаи.