Объявление переменных внутри C switch/case

Ну, это на самом деле не вопрос..

Я только что случайно обнаружил, что есть интересный способ объявить локальные переменные внутри блока switch / case. Вместо использования фигурных скобок внутри каждого блока case вы можете написать:

switch (action) {
  int res;
  int value;
case ACTION_OPEN:
  res = open(...);
  ...
  break;
case  ...
}

Итак, мне просто интересно, что компиляторы C/C++ помимо gcc поддерживают эту конструкцию? Это похоже на общий провал. Любые комментарии по этой конструкции приветствуются!

4 ответа

Решение

Любой соответствующий стандартам компилятор C или C++ позволит это сделать. Даже старомодный (до ISO C99) C-компилятор позволит это, но только потому, что объявления переменных находятся в начале оператора блока / соединения (обозначается как {}).

Обратите внимание, что то, что следует за switch это почти нормальное утверждение, за исключением возможности метки регистра:

int main(int argc, char* argv[])
{
    switch (argc)
      default:
        puts("Hello, world!");

    return 0;
}

Так что в ANSI C89 именно фигурные скобки делают здесь магию.

Тело переключателя - это просто нормальный оператор (в вашем случае составной оператор выглядит как { ... }) который может содержать любую хрень. Включая этикетки на корпус.

Эта философия переключения злоупотребляется устройством Duffs.

Многие люди не понимают, что даже что-то вроде switch(0) ; является допустимым оператором (вместо составного оператора он имеет нулевой оператор в качестве тела), хотя и совершенно бесполезен.

Строго говоря, дело, которое вы представляете с int разрешено на всех трех языках, но по разным причинам.

C позволяет перейти через определение любой локальной переменной (арифметика, struct, union, массив...) во всех случаях (для C89) и во всех случаях, кроме одного (для C99). Исключением для C99 являются массивы переменной длины.

C++ допускает это только для типов данных, которые не имеют конструктора или деструктора, часто называемого POD.

Так что если у вас есть тип T вместо int в вашем примере в C89 это всегда допустимо, а в C99 и C++ это зависит от типа T действительно ли это правильно.

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

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

Другие вопросы по тегам