Код перед первым "случаем" в switch-statement

В C можно написать код до первой метки case. Существуют ли какие-либо случаи, для которых это полезно, или это просто "мертвый блок кода"?

например:.

switch (...)    {
  {
    int a = 0x2a;
    printf("%d\n", a);
  }
  case 0:
    ...
}

Ответы

Ответ 1

Может быть полезно объявить переменные, которые имеют область действия, ограниченную блоком switch (но имейте в виду, что любые инициализаторы для этих переменных будут пропущены):

switch (...)
{
    int n;

    case 0:
    ...
}

В теории вы также можете добавить код, который вы можете использовать goto.

Ответ 2

Я думаю, что это менее особенность, чем артефакт того, как C рассматривает switch/case - как раз ряд целей перехода без ограничений на синтаксис. Вот почему устройство Duff работает, а также почему код до первого case никогда не будет запущен.

Если вы посмотрите на сгенерированную сборку, вы увидите, что код просто перепрыгнут:

    mov ecx, DWORD PTR _x$[ebp]
    mov DWORD PTR tv64[ebp], ecx
    cmp DWORD PTR tv64[ebp], 0                  ; here begins the switch
    je  SHORT [email protected]                         ; jump to case 0
    jmp SHORT [email protected]                         ; jump out of the switch
; Line 8
    mov DWORD PTR _a$752[ebp], 42
; Line 9
    mov edx, DWORD PTR _a$752[ebp]              ; here we have the dead code
    push    edx
    push    OFFSET $SG754
    call    _printf
    add esp, 8
[email protected]:                                      ; and here case 0
; Line 12
    push    OFFSET $SG756
    call    _printf
    add esp, 4
[email protected]:
; Line 15
    xor eax, eax
    mov esp, ebp
    pop ebp
    ret 0

Ответ 3

В стандартном документе C есть пример, который точно объясняет поведение этого типа конструкции (6.8.4.2/7 "Оператор switch" ):

ПРИМЕР В фрагменте художественной программы

switch (expr)
{
    int i = 4;
    f(i);
case 0:
    i  =  17;
    /*  falls through into default code  */
default:
    printf("%d\n", i);
}

объект с идентификатором i существует с автоматической продолжительностью хранения (внутри блока), но никогда не инициализируется, и, следовательно, если управляющее выражение имеет ненулевое значение, вызов функции printf будет иметь доступ к неопределенному значению, Аналогично, вызов функции f невозможен.

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

Ответ 4

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

int a = 0x2a;
printf("%d\n", a);
switch (...)    {
case 0:
...
}

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