Код перед первым "случаем" в 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:
...
}
Разве это не то, что вы намерены? (кроме вашего примера, код никогда не будет работать, если компилятор не жалуется.)