Объявление переменных внутри 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 позволяет объявлять переменные (почти) везде, где вы хотите, внутри блоков, так что поведение должно рассматриваться как допустимое... и я не вижу никакого реального риска, так как это просто декларация.